Re: [libvirt] PATCH: 21/25: Use random_r for random numbers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Now that gnulib's rand module is imported, we have a decent
quality random number generator that's portable. We don't
want to mess with the apps state, so in virInitialize() we
explicitly initialize our own private random nubmer generator
state with virRandomInitialize().

The util.h file gains a convenience macro, since random_r()
is horrible to call and we need to protect our global state

   int virRandom(int max)


 Makefile.maint |    2 +-
 src/libvirt.c  |    3 ++-
 src/util.c     |   38 +++++++++++++++++++++++++++++++++++---
 src/util.h     |    3 +++
 src/uuid.c     |    4 ++--
 5 files changed, 43 insertions(+), 7 deletions(-)

Daniel

diff --git a/Makefile.maint b/Makefile.maint
--- a/Makefile.maint
+++ b/Makefile.maint
@@ -117,7 +117,7 @@ sc_prohibit_nonreentrant:
 	@fail=0 ; \
 	for i in $(NON_REENTRANT) ; \
 	do \
-	   grep -nE "\<$$i\>[:space:]*\(" $$($(VC_LIST_EXCEPT)) && \
+	   grep --before 2 --after 1 -nE "\<$$i\>[:space:]*\(" $$($(VC_LIST_EXCEPT)) && \
 	     fail=1 && echo "$(ME): use $${i}_r, not $${i}" || : ; \
 	done ; \
 	exit $$fail
diff --git a/src/libvirt.c b/src/libvirt.c
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -257,7 +257,8 @@ virInitialize(void)
     initialized = 1;
 
     if (virThreadInitialize() < 0 ||
-        virErrorInitialize() < 0)
+        virErrorInitialize() < 0 ||
+        virRandomInitialize())
         return -1;
 
 #ifdef ENABLE_DEBUG
diff --git a/src/util.c b/src/util.c
--- a/src/util.c
+++ b/src/util.c
@@ -32,6 +32,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <poll.h>
+#include <time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
@@ -56,6 +57,7 @@
 #include "buf.h"
 #include "util.h"
 #include "memory.h"
+#include "threads.h"
 
 #ifndef NSIG
 # define NSIG 32
@@ -1282,9 +1284,9 @@ void virGenerateMacAddr(const unsigned c
     addr[0] = prefix[0];
     addr[1] = prefix[1];
     addr[2] = prefix[2];
-    addr[3] = (int)(256*(rand()/(RAND_MAX+1.0)));
-    addr[4] = (int)(256*(rand()/(RAND_MAX+1.0)));
-    addr[5] = (int)(256*(rand()/(RAND_MAX+1.0)));
+    addr[3] = virRandom(256);
+    addr[4] = virRandom(256);
+    addr[5] = virRandom(256);
 }
 
 
@@ -1431,3 +1433,33 @@ int virKillProcess(pid_t pid, int sig)
     return kill(pid, sig);
 #endif
 }
+
+
+static char randomState[128];
+static struct random_data randomData;
+static virMutex randomLock;
+
+int virRandomInitialize(void)
+{
+    if (virMutexInit(&randomLock) < 0)
+        return -1;
+
+    if (initstate_r(time(NULL),
+                    randomState,
+                    sizeof(randomState),
+                    &randomData) < 0)
+        return -1;
+
+    return 0;
+}
+
+int virRandom(int max)
+{
+    int32_t ret;
+
+    virMutexLock(&randomLock);
+    random_r(&randomData, &ret);
+    virMutexUnlock(&randomLock);
+
+    return (int) ((double)max * ((double)ret / (double)RAND_MAX));
+}
diff --git a/src/util.h b/src/util.h
--- a/src/util.h
+++ b/src/util.h
@@ -172,4 +172,7 @@ char *virGetHostname(void);
 
 int virKillProcess(pid_t pid, int sig);
 
+int virRandomInitialize(void);
+int virRandom(int max);
+
 #endif /* __VIR_UTIL_H__ */
diff --git a/src/uuid.c b/src/uuid.c
--- a/src/uuid.c
+++ b/src/uuid.c
@@ -35,6 +35,7 @@
 
 #include "c-ctype.h"
 #include "internal.h"
+#include "util.h"
 
 #define qemudLog(level, msg...) fprintf(stderr, msg)
 
@@ -74,9 +75,8 @@ virUUIDGeneratePseudoRandomBytes(unsigne
 virUUIDGeneratePseudoRandomBytes(unsigned char *buf,
                                  int buflen)
 {
-    srand(time(NULL));
     while (buflen > 0) {
-        *buf = (int) (255.0 * (rand() / (double) RAND_MAX));
+        *buf = virRandom(256);
         buflen--;
     }
 

-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

--
Libvir-list mailing list
Libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]