]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/randutils.c: Fall back gracefully when kernel doesn't support getrandom(2).
authorChristopher James Halse Rogers <raof@ubuntu.com>
Mon, 7 Aug 2017 06:07:54 +0000 (16:07 +1000)
committerKarel Zak <kzak@redhat.com>
Wed, 20 Sep 2017 12:15:43 +0000 (14:15 +0200)
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()

lib/randutils.c

index 09dd2618601fae3acc9052aa0de5ae6174cbbea3..ceeb474eff49392f986a11743092dc6efadda94e 100644 (file)
@@ -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.