Skip to content

Commit

Permalink
Merge pull request #25 from dsprenkels/issue_22
Browse files Browse the repository at this point in the history
Fallback to old-style entropy count if ioctl returns ENOSYS
  • Loading branch information
dsprenkels committed Oct 17, 2019
2 parents 4e986bb + a697b4c commit 6db39aa
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Makefile
@@ -1,4 +1,4 @@
CFLAGS := -g -O2 -m64 -std=gnu99 \
CFLAGS ?= -g -O2 -std=gnu99 \
-Wall -Wextra -Wshadow -Wpointer-arith -Wcast-qual -Wformat \
-Wformat-security -Werror=format-security -Wstrict-prototypes \
-D_FORTIFY_SOURCE=2 -fPIC -fno-strict-overflow
Expand Down
16 changes: 11 additions & 5 deletions randombytes.c
Expand Up @@ -138,11 +138,17 @@ static int randombytes_linux_wait_for_entropy(int device)

/* If the device has enough entropy already, we will want to return early */
retcode = randombytes_linux_read_entropy_ioctl(device, &entropy);
if (retcode != 0 && errno == ENOTTY) {
/* The ioctl call on /dev/urandom has failed due to a ENOTTY (i.e.
* unsupported action). We will fall back to reading from
* `/proc/sys/kernel/random/entropy_avail`. This is obviously less
* ideal, but at this point it seems we have no better option. */
// printf("errno: %d (%s)\n", errno, strerror(errno));
if (retcode != 0 && (errno == ENOTTY || errno == ENOSYS)) {
// The ioctl call on /dev/urandom has failed due to a
// - ENOTTY (unsupported action), or
// - ENOSYS (invalid ioctl; this happens on MIPS, see #22).
//
// We will fall back to reading from
// `/proc/sys/kernel/random/entropy_avail`. This less ideal,
// because it allocates a file descriptor, and it may not work
// in a chroot. But at this point it seems we have no better
// options left.
strategy = PROC;
// Open the entropy count file
proc_file = fopen("/proc/sys/kernel/random/entropy_avail", "r");
Expand Down
15 changes: 15 additions & 0 deletions randombytes_test.c
Expand Up @@ -87,6 +87,15 @@ static void test_issue_17(void) {
assert(memcmp(buf1, buf2, sizeof(buf1)) != 0);
}

static void test_issue_22(void) {
uint8_t buf1[20] = {}, buf2[sizeof(buf1)] = {};
const int ret1 = randombytes(buf1, sizeof(buf1));
const int ret2 = randombytes(buf2, sizeof(buf2));
assert(ret1 == 0);
assert(ret2 == 0);
assert(memcmp(buf1, buf2, sizeof(buf1)) != 0);
}

// ======== Mock OS functions to simulate uncommon behavior ========

#if defined(__linux__) && defined(SYS_getrandom)
Expand All @@ -112,6 +121,10 @@ int __wrap_ioctl(int fd, int code, int* ret) {
errno = ENOTTY;
return -1;
}
if (current_test == test_issue_17) {
errno = ENOSYS;
return -1;
}
return __real_ioctl(fd, code, ret);
}
#endif /* defined(__linux__) && !defined(SYS_getrandom) */
Expand All @@ -133,8 +146,10 @@ int main(void) {
#endif /* defined(__linux__) && defined(SYS_getrandom) */
#if defined(__linux__) && !defined(SYS_getrandom)
RUN_TEST(test_issue_17)
RUN_TEST(test_issue_22)
#else
SKIP_TEST(test_issue_17)
SKIP_TEST(test_issue_22)
#endif /* defined(__linux__) && !defined(SYS_getrandom) */
return 0;
}

0 comments on commit 6db39aa

Please sign in to comment.