]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
virrandom: make virRandomInitialize an automatic one-shot
authorEric Blake <eblake@redhat.com>
Fri, 3 Aug 2012 23:15:00 +0000 (17:15 -0600)
committerEric Blake <eblake@redhat.com>
Mon, 6 Aug 2012 14:15:13 +0000 (08:15 -0600)
All callers used the same initialization seed (well, the new
viratomictest forgot to look at getpid()); so we might as well
make this value automatic.  And while it may feel like we are
giving up functionality, I documented how to get it back in the
unlikely case that you actually need to debug with a fixed
pseudo-random sequence.  I left that crippled by default, so
that a stray environment variable doesn't cause a lack of
randomness to become a security issue.

* src/util/virrandom.c (virRandomInitialize): Rename...
(virRandomOnceInit): ...and make static, with one-shot call.
Document how to do fixed-seed debugging.
* src/util/virrandom.h (virRandomInitialize): Drop prototype.
* src/libvirt_private.syms (virrandom.h): Don't export it.
* src/libvirt.c (virInitialize): Adjust caller.
* src/lxc/lxc_controller.c (main): Likewise.
* src/security/virt-aa-helper.c (main): Likewise.
* src/util/iohelper.c (main): Likewise.
* tests/seclabeltest.c (main): Likewise.
* tests/testutils.c (virtTestMain): Likewise.
* tests/viratomictest.c (mymain): Likewise.

src/libvirt.c
src/libvirt_private.syms
src/lxc/lxc_controller.c
src/security/virt-aa-helper.c
src/util/iohelper.c
src/util/virrandom.c
src/util/virrandom.h
tests/seclabeltest.c
tests/testutils.c
tests/viratomictest.c

index 3c4bf8ca0c8cae76ee4c3472b45ee9c9e1f4abd7..0a91d0fe92e866b870fd58dc99f82c6f8c00c104 100644 (file)
@@ -408,8 +408,7 @@ virInitialize(void)
     initialized = 1;
 
     if (virThreadInitialize() < 0 ||
-        virErrorInitialize() < 0 ||
-        virRandomInitialize(time(NULL) ^ getpid()))
+        virErrorInitialize() < 0)
         return -1;
 
     gcry_control(GCRYCTL_SET_THREAD_CBS, &virTLSThreadImpl);
index 44b6652e4904428c0ccba42ccd988cd933915de5..6b98c9c3ed1203cee09e19592f9012a9d253076b 100644 (file)
@@ -1663,7 +1663,6 @@ virPidFileDeletePath;
 # virrandom.h
 virRandomBits;
 virRandomGenerateWWN;
-virRandomInitialize;
 
 
 # virsocketaddr.h
index 56ed7d31953467ee900666facc4dbda32e1b752d..8ff925e56662a20418c416353bca8ad7d8739619 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2010-2012 Red Hat, Inc.
  * Copyright IBM Corp. 2008
  *
  * lxc_controller.c: linux container process controller
@@ -1480,8 +1480,7 @@ int main(int argc, char *argv[])
 
     if (setlocale(LC_ALL, "") == NULL ||
         bindtextdomain(PACKAGE, LOCALEDIR) == NULL ||
-        textdomain(PACKAGE) == NULL ||
-        virRandomInitialize(time(NULL) ^ getpid())) {
+        textdomain(PACKAGE) == NULL) {
         fprintf(stderr, _("%s: initialization failed\n"), argv[0]);
         exit(EXIT_FAILURE);
     }
index 5352a4a6e83569d22bc6d292c25024897188ad57..4c2f487bd30b14ba0d126c619cdf1447df40800e 100644 (file)
@@ -1199,9 +1199,6 @@ main(int argc, char **argv)
 
     memset(ctl, 0, sizeof(vahControl));
 
-    if (virRandomInitialize(time(NULL) ^ getpid()) < 0)
-        vah_error(ctl, 1, _("could not initialize random generator"));
-
     if (vahParseArgv(ctl, argc, argv) != 0)
         vah_error(ctl, 1, _("could not parse arguments"));
 
index 0732cac7b1466ed95ae498c8176670c80186beac..4791234073a7bf63815030ae054aa3707a72d44f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * iohelper.c: Helper program to perform I/O operations on files
  *
- * Copyright (C) 2011 Red Hat, Inc.
+ * Copyright (C) 2011-2012 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -230,8 +230,7 @@ main(int argc, char **argv)
     }
 
     if (virThreadInitialize() < 0 ||
-        virErrorInitialize() < 0 ||
-        virRandomInitialize(time(NULL) ^ getpid())) {
+        virErrorInitialize() < 0) {
         fprintf(stderr, _("%s: initialization failed\n"), program_name);
         exit(EXIT_FAILURE);
     }
index b815ce2ace0f4a70d7015a42caa23663a9a8b7f6..50bed469ece219a7db71407dbca9c531e3ba3c3f 100644 (file)
@@ -29,6 +29,7 @@
 #include "count-one-bits.h"
 #include "util.h"
 #include "virterror_internal.h"
+#include "logging.h"
 
 #define VIR_FROM_THIS VIR_FROM_NONE
 
@@ -37,8 +38,21 @@ static struct random_data randomData;
 static virMutex randomLock;
 
 
-int virRandomInitialize(uint32_t seed)
+static int
+virRandomOnceInit(void)
 {
+    unsigned int seed = time(NULL) ^ getpid();
+
+#if 0
+    /* Normally we want a decent seed.  But if reproducible debugging
+     * of a fixed pseudo-random sequence is ever required, uncomment
+     * this block to let an environment variable force the seed.  */
+    const char *debug = getenv("VIR_DEBUG_RANDOM_SEED");
+
+    if (debug && virStrToLong_ui(debug, NULL, 0, &seed) < 0)
+        return -1;
+#endif
+
     if (virMutexInit(&randomLock) < 0)
         return -1;
 
@@ -51,6 +65,8 @@ int virRandomInitialize(uint32_t seed)
     return 0;
 }
 
+VIR_ONCE_GLOBAL_INIT(virRandom)
+
 /* The algorithm of virRandomBits requires that RAND_MAX == 2^n-1 for
  * some n; gnulib's random_r meets this property. */
 verify(((RAND_MAX + 1U) & RAND_MAX) == 0);
@@ -70,6 +86,13 @@ uint64_t virRandomBits(int nbits)
     uint64_t ret = 0;
     int32_t bits;
 
+    if (virRandomInitialize() < 0) {
+        /* You're already hosed, so this particular non-random value
+         * isn't any worse.  */
+        VIR_WARN("random number generation is broken");
+        return 0;
+    }
+
     virMutexLock(&randomLock);
 
     while (nbits > bits_per_iter) {
index aa2c8b43f974f6cd2cae48ee0d18a2c069acffe3..8d3cad722513521f4dabde72867fc1aff6086c50 100644 (file)
@@ -25,7 +25,6 @@
 # include "internal.h"
 # include <stdint.h>
 
-int virRandomInitialize(uint32_t seed) ATTRIBUTE_RETURN_CHECK;
 uint64_t virRandomBits(int nbits);
 int virRandomGenerateWWN(char **wwn, const char *virt_type);
 
index 45ab8e4e709a7e6c19b506873059432d8519e8ed..81ef323934db64899a5084fae3e7f2195267012a 100644 (file)
@@ -14,8 +14,7 @@ main (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
     virSecurityManagerPtr mgr;
     const char *doi, *model;
 
-    if (virThreadInitialize() < 0 ||
-        virRandomInitialize(time(NULL) ^ getpid()))
+    if (virThreadInitialize() < 0)
         exit(EXIT_FAILURE);
 
     mgr = virSecurityManagerNew(NULL, "QEMU", false, true, false);
index 171321f65e18bdab1f10b53a9d3371dd9497b32e..ecd3d2d74065beb6c6f44e785e235a1bbacb0a3d 100644 (file)
@@ -603,8 +603,7 @@ int virtTestMain(int argc,
     fprintf(stderr, "TEST: %s\n", progname);
 
     if (virThreadInitialize() < 0 ||
-        virErrorInitialize() < 0 ||
-        virRandomInitialize(time(NULL) ^ getpid()))
+        virErrorInitialize() < 0)
         return 1;
 
     virLogSetFromEnv();
index 48f0d24df2cbe80f34c4090b2d0651fb7f832dd1..772fbfebb77d5b4144fb0b511f49762e4c0df0be 100644 (file)
@@ -165,8 +165,6 @@ mymain(void)
 {
     int ret = 0;
 
-    if (virRandomInitialize(time(NULL)) < 0)
-        return -1;
     if (virThreadInitialize() < 0)
         return -1;