]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libuuid: avoid double open and leaking fd (reworked)
authorPetr Uzel <petr.uzel@suse.cz>
Sun, 6 May 2012 19:55:53 +0000 (21:55 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 10 May 2012 09:43:49 +0000 (11:43 +0200)
This reverts commit 6126f7a53c57485a9a29ddd772765695f23c92e6
and fixes the double open and leaking descriptor in a different way,
that is by using newly introduced function 'have_random_source()'
to check whether good random source is available while deciding
which uuid type to generate (random/time).

This is better than calling random_get_fd() twice, passing the file
descriptor down the stack and reusing it in next call to
random_get_fd().

Signed-off-by: Petr Uzel <petr.uzel@suse.cz>
fdisk/fdiskdoslabel.c
include/randutils.h
lib/randutils.c
libuuid/src/gen_uuid.c
libuuid/src/uuidd.h
misc-utils/uuidd.c

index a1916fc573837cdfa9ce01f1122146a3f467876a..34bcde6e7ab34c533d23ada264de4d82785933c5 100644 (file)
@@ -224,7 +224,7 @@ void create_doslabel(void)
        unsigned int id;
 
        /* random disk signature */
-       random_get_bytes(&id, sizeof(id), -1);
+       random_get_bytes(&id, sizeof(id));
 
        fprintf(stderr, _("Building a new DOS disklabel with disk identifier 0x%08x.\n"), id);
 
index d5d00f46932c1cfca5e6e6f6acc13c01353e046a..dec5e355a43947a0133087a9ef2fcd1181b0da99 100644 (file)
@@ -7,6 +7,6 @@
 #endif
 
 extern int random_get_fd(void);
-extern void random_get_bytes(void *buf, size_t nbytes, int fd);
+extern void random_get_bytes(void *buf, size_t nbytes);
 
 #endif
index 0513798a0320b376256cc95d99d5ed59b82561f1..b90c88691a5e9349a8fb415ab80383684117ad5c 100644 (file)
@@ -58,15 +58,13 @@ int random_get_fd(void)
  * Use /dev/urandom if possible, and if not,
  * use glibc pseudo-random functions.
  */
-void random_get_bytes(void *buf, size_t nbytes, int fd)
+void random_get_bytes(void *buf, size_t nbytes)
 {
        size_t i, n = nbytes;
+       int fd = random_get_fd();
        int lose_counter = 0;
        unsigned char *cp = (unsigned char *) buf;
 
-       if (fd < 0)
-               fd = random_get_fd();
-
        if (fd >= 0) {
                while (n > 0) {
                        ssize_t x = read(fd, cp, n);
@@ -113,7 +111,7 @@ int main(int argc, char *argv[])
 
        /* generate and print 10 random numbers */
        for (i = 0; i < 10; i++) {
-               random_get_bytes(&v, sizeof(v), -1);
+               random_get_bytes(&v, sizeof(v));
                printf("%d\n", v);
        }
 
index 76f1bbdad5c20ba9885b69e6346bcb77a585e6e2..93d292a22d36f784d42471816e6cb2cf87e99f2b 100644 (file)
@@ -277,7 +277,7 @@ static int get_clock(uint32_t *clock_high, uint32_t *clock_low,
        }
 
        if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
-               random_get_bytes(&clock_seq, sizeof(clock_seq), -1);
+               random_get_bytes(&clock_seq, sizeof(clock_seq));
                clock_seq &= 0x3FFF;
                gettimeofday(&last, 0);
                last.tv_sec--;
@@ -434,7 +434,7 @@ int __uuid_generate_time(uuid_t out, int *num)
 
        if (!has_init) {
                if (get_node_id(node_id) <= 0) {
-                       random_get_bytes(node_id, 6, -1);
+                       random_get_bytes(node_id, 6);
                        /*
                         * Set multicast bit, to prevent conflicts
                         * with IEEE 802 addresses obtained from
@@ -520,7 +520,7 @@ int uuid_generate_time_safe(uuid_t out)
 }
 
 
-void __uuid_generate_random(uuid_t out, int *num, int fd)
+void __uuid_generate_random(uuid_t out, int *num)
 {
        uuid_t  buf;
        struct uuid uu;
@@ -532,7 +532,7 @@ void __uuid_generate_random(uuid_t out, int *num, int fd)
                n = *num;
 
        for (i = 0; i < n; i++) {
-               random_get_bytes(buf, sizeof(buf), fd);
+               random_get_bytes(buf, sizeof(buf));
                uuid_unpack(buf, &uu);
 
                uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
@@ -548,7 +548,18 @@ void uuid_generate_random(uuid_t out)
        int     num = 1;
        /* No real reason to use the daemon for random uuid's -- yet */
 
-       __uuid_generate_random(out, &num, -1);
+       __uuid_generate_random(out, &num);
+}
+
+/*
+ * Check whether good random source (/dev/random or /dev/urandom)
+ * is available.
+ */
+static int have_random_source(void)
+{
+       struct stat s;
+
+       return (!stat("/dev/random", &s) || !stat("/dev/urandom", &s));
 }
 
 
@@ -560,11 +571,8 @@ void uuid_generate_random(uuid_t out)
  */
 void uuid_generate(uuid_t out)
 {
-       int     fd;
-       int     num = 1;
-
-       if ((fd = random_get_fd()) >= 0)
-               __uuid_generate_random(out, &num, fd);
+       if (have_random_source())
+               uuid_generate_random(out);
        else
                uuid_generate_time(out);
 }
index 2e19522df123ea62378bc059ad01c2ceb64e49f3..27b79c2160f6bb7896ae43dba37bcf07912f81f8 100644 (file)
@@ -49,6 +49,6 @@
 #define UUIDD_MAX_OP                   UUIDD_OP_BULK_RANDOM_UUID
 
 extern int __uuid_generate_time(uuid_t out, int *num);
-extern void __uuid_generate_random(uuid_t out, int *num, int fd);
+extern void __uuid_generate_random(uuid_t out, int *num);
 
 #endif /* _UUID_UUID_H */
index 768fed54616bdf0eeac1896413be80e00df71052..eb1ef02c64387176ee475027426e94477085ab26 100644 (file)
@@ -442,7 +442,7 @@ static void server_loop(const char *socket_path, const char *pidfile_path,
                        break;
                case UUIDD_OP_RANDOM_UUID:
                        num = 1;
-                       __uuid_generate_random(uu, &num, -1);
+                       __uuid_generate_random(uu, &num);
                        if (uuidd_cxt->debug) {
                                uuid_unparse(uu, str);
                                fprintf(stderr, _("Generated random UUID: %s\n"), str);
@@ -473,7 +473,7 @@ static void server_loop(const char *socket_path, const char *pidfile_path,
                        if (num * UUID_LEN > (int) (sizeof(reply_buf) - sizeof(num)))
                                num = (sizeof(reply_buf) - sizeof(num)) / UUID_LEN;
                        __uuid_generate_random((unsigned char *) reply_buf +
-                                             sizeof(num), &num, -1);
+                                             sizeof(num), &num);
                        if (uuidd_cxt->debug) {
                                fprintf(stderr, P_("Generated %d UUID:\n",
                                                   "Generated %d UUIDs:\n", num), num);