[systemd-commits] 2 commits - src/libsystemd-terminal src/shared src/udev

Lennart Poettering lennart at kemper.freedesktop.org
Thu Oct 30 07:36:22 PDT 2014


 src/libsystemd-terminal/modeset.c |    2 
 src/shared/missing.h              |    8 +++
 src/shared/util.c                 |   77 ++++++++++++++++++++++++--------------
 src/shared/util.h                 |    1 
 src/udev/cdrom_id/cdrom_id.c      |    2 
 src/udev/scsi_id/scsi_serial.c    |    2 
 6 files changed, 62 insertions(+), 30 deletions(-)

New commits:
commit ef309a681f4c761503e4cd4cc6884d7d6ef70436
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Oct 30 15:35:37 2014 +0100

    util: unify how we see srand()

diff --git a/src/libsystemd-terminal/modeset.c b/src/libsystemd-terminal/modeset.c
index f5be38e..f0508d7 100644
--- a/src/libsystemd-terminal/modeset.c
+++ b/src/libsystemd-terminal/modeset.c
@@ -480,7 +480,7 @@ int main(int argc, char *argv[]) {
         log_parse_environment();
         log_open();
 
-        srand(time(NULL));
+        initialize_srand();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
diff --git a/src/shared/util.c b/src/shared/util.c
index 1d67abe..0f44eb5 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -2521,8 +2521,36 @@ int dev_urandom(void *p, size_t n) {
         return 0;
 }
 
-void random_bytes(void *p, size_t n) {
+void initialize_srand(void) {
         static bool srand_called = false;
+        unsigned x;
+#ifdef HAVE_SYS_AUXV_H
+        void *auxv;
+#endif
+
+        if (srand_called)
+                return;
+
+        x = 0;
+
+#ifdef HAVE_SYS_AUXV_H
+        /* The kernel provides us with a bit of entropy in auxv, so
+         * let's try to make use of that to seed the pseudo-random
+         * generator. It's better than nothing... */
+
+        auxv = (void*) getauxval(AT_RANDOM);
+        if (auxv)
+                x ^= *(unsigned*) auxv;
+#endif
+
+        x ^= (unsigned) now(CLOCK_REALTIME);
+        x ^= (unsigned) gettid();
+
+        srand(x);
+        srand_called = true;
+}
+
+void random_bytes(void *p, size_t n) {
         uint8_t *q;
         int r;
 
@@ -2533,28 +2561,7 @@ void random_bytes(void *p, size_t n) {
         /* If some idiot made /dev/urandom unavailable to us, he'll
          * get a PRNG instead. */
 
-        if (!srand_called) {
-                unsigned x = 0;
-
-#ifdef HAVE_SYS_AUXV_H
-                /* The kernel provides us with a bit of entropy in
-                 * auxv, so let's try to make use of that to seed the
-                 * pseudo-random generator. It's better than
-                 * nothing... */
-
-                void *auxv;
-
-                auxv = (void*) getauxval(AT_RANDOM);
-                if (auxv)
-                        x ^= *(unsigned*) auxv;
-#endif
-
-                x ^= (unsigned) now(CLOCK_REALTIME);
-                x ^= (unsigned) gettid();
-
-                srand(x);
-                srand_called = true;
-        }
+        initialize_srand();
 
         for (q = p; q < (uint8_t*) p + n; q ++)
                 *q = rand();
diff --git a/src/shared/util.h b/src/shared/util.h
index 3558446..aad9eb7 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -321,6 +321,7 @@ int make_console_stdio(void);
 
 int dev_urandom(void *p, size_t n);
 void random_bytes(void *p, size_t n);
+void initialize_srand(void);
 
 static inline uint64_t random_u64(void) {
         uint64_t u;
diff --git a/src/udev/cdrom_id/cdrom_id.c b/src/udev/cdrom_id/cdrom_id.c
index 7a4b987..5fe3fb5 100644
--- a/src/udev/cdrom_id/cdrom_id.c
+++ b/src/udev/cdrom_id/cdrom_id.c
@@ -922,7 +922,7 @@ int main(int argc, char *argv[])
                 goto exit;
         }
 
-        srand((unsigned int)getpid());
+        initialize_srand();
         for (cnt = 20; cnt > 0; cnt--) {
                 struct timespec duration;
 
diff --git a/src/udev/scsi_id/scsi_serial.c b/src/udev/scsi_id/scsi_serial.c
index b3d20a3..9338671 100644
--- a/src/udev/scsi_id/scsi_serial.c
+++ b/src/udev/scsi_id/scsi_serial.c
@@ -861,7 +861,7 @@ int scsi_get_serial(struct udev *udev,
         int retval;
 
         memzero(dev_scsi->serial, len);
-        srand((unsigned int)getpid());
+        initialize_srand();
         for (cnt = 20; cnt > 0; cnt--) {
                 struct timespec duration;
 

commit 97768fc5746ea97cb2d3ac6854b4fc7ce1c14f24
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Oct 30 15:27:53 2014 +0100

    util: don't block on getrandom()

diff --git a/src/shared/missing.h b/src/shared/missing.h
index 85d3fec..7725e47 100644
--- a/src/shared/missing.h
+++ b/src/shared/missing.h
@@ -149,6 +149,14 @@ static inline int getrandom(void *buffer, size_t count, unsigned flags) {
 }
 #endif
 
+#ifndef GRND_NONBLOCK
+#define GRND_NONBLOCK 0x0001
+#endif
+
+#ifndef GRND_RANDOM
+#define GRND_RANDOM 0x0002
+#endif
+
 #ifndef BTRFS_IOCTL_MAGIC
 #define BTRFS_IOCTL_MAGIC 0x94
 #endif
diff --git a/src/shared/util.c b/src/shared/util.c
index ceafba8..1d67abe 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -2470,10 +2470,17 @@ int dev_urandom(void *p, size_t n) {
         int r, fd;
         ssize_t k;
 
-        /* Use the syscall unless we know we don't have it, or when
-         * the requested size is too large for it. */
+        /* Gathers some randomness from the kernel. This call will
+         * never block, and will always return some data from the
+         * kernel, regardless if the random pool is fully initialized
+         * or not. It thus makes no guarantee for the quality of the
+         * returned entropy, but is good enough for or usual usecases
+         * of seeding the hash functions for hashtable */
+
+        /* Use the getrandom() syscall unless we know we don't have
+         * it, or when the requested size is too large for it. */
         if (have_syscall != 0 || (size_t) (int) n != n) {
-                r = getrandom(p, n, 0);
+                r = getrandom(p, n, GRND_NONBLOCK);
                 if (r == (int) n) {
                         have_syscall = true;
                         return 0;
@@ -2481,8 +2488,17 @@ int dev_urandom(void *p, size_t n) {
 
                 if (r < 0) {
                         if (errno == ENOSYS)
-                                /* we lack the syscall, continue with reading from /dev/urandom */
+                                /* we lack the syscall, continue with
+                                 * reading from /dev/urandom */
                                 have_syscall = false;
+                        else if (errno == EAGAIN)
+                                /* not enough entropy for now. Let's
+                                 * remember to use the syscall the
+                                 * next time, again, but also read
+                                 * from /dev/urandom for now, which
+                                 * doesn't care about the current
+                                 * amount of entropy.  */
+                                have_syscall = true;
                         else
                                 return -errno;
                 } else



More information about the systemd-commits mailing list