summaryrefslogtreecommitdiffstats
path: root/lib/randutils.c
diff options
context:
space:
mode:
authorChristopher James Halse Rogers2017-08-07 08:07:54 +0200
committerChristopher James Halse Rogers2017-08-08 03:27:49 +0200
commita7df0f5f3537d062dcf2f7d85cf2f919bf384b16 (patch)
treecc1a9677b21be0751dedbded8cb2fa12db3d00f5 /lib/randutils.c
parentlibblkid: add support for UBI superblock (diff)
downloadkernel-qcow2-util-linux-a7df0f5f3537d062dcf2f7d85cf2f919bf384b16.tar.gz
kernel-qcow2-util-linux-a7df0f5f3537d062dcf2f7d85cf2f919bf384b16.tar.xz
kernel-qcow2-util-linux-a7df0f5f3537d062dcf2f7d85cf2f919bf384b16.zip
lib/randutils.c: Fall back gracefully when kernel doesn't support getrandom(2).
The 3.16 kernel is supported until 2020, and various distros have kernels of the same vintage. It's entirely possible for code built against newer headers to be run against these kernels, so fall-back to the old “read /dev/{u,}random” method if the kernel doesn' support getrandom()
Diffstat (limited to 'lib/randutils.c')
-rw-r--r--lib/randutils.c44
1 files changed, 26 insertions, 18 deletions
diff --git a/lib/randutils.c b/lib/randutils.c
index 09dd26186..ceeb474ef 100644
--- a/lib/randutils.c
+++ b/lib/randutils.c
@@ -99,32 +99,40 @@ void random_get_bytes(void *buf, size_t nbytes)
unsigned char *cp = (unsigned char *)buf;
#ifdef HAVE_GETRANDOM
+ errno = 0;
while (getrandom(buf, nbytes, 0) < 0) {
if (errno == EINTR)
continue;
break;
}
-#else
- size_t n = nbytes;
- int fd = random_get_fd();
- int lose_counter = 0;
-
- if (fd >= 0) {
- while (n > 0) {
- ssize_t x = read(fd, cp, n);
- if (x <= 0) {
- if (lose_counter++ > 16)
- break;
- continue;
+ if (errno == ENOSYS)
+ /*
+ * We've been built against headers that support getrandom,
+ * but the running kernel does not.
+ * Fallback to reading from /dev/{u,}random as before
+ */
+#endif
+ {
+ size_t n = nbytes;
+ int fd = random_get_fd();
+ int lose_counter = 0;
+
+ if (fd >= 0) {
+ while (n > 0) {
+ ssize_t x = read(fd, cp, n);
+ if (x <= 0) {
+ if (lose_counter++ > 16)
+ break;
+ continue;
+ }
+ n -= x;
+ cp += x;
+ lose_counter = 0;
}
- n -= x;
- cp += x;
- lose_counter = 0;
- }
- close(fd);
+ close(fd);
+ }
}
-#endif
/*
* We do this all the time, but this is the only source of
* randomness if /dev/random/urandom is out to lunch.