Source-Changes-HG archive

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

[src/trunk]: src/sbin/gpt Make gpt(8) generate v4 (random) uuids.



details:   https://anonhg.NetBSD.org/src/rev/a6d202e0887f
branches:  trunk
changeset: 332687:a6d202e0887f
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sat Oct 04 10:30:13 2014 +0000

description:
Make gpt(8) generate v4 (random) uuids.

Don't needlessly leak your date/time and MAC address when you edit
the disk.

Read from /dev/urandom rather than calling arc4random or anything,
since this is a tool.  (Cygwin seems to have /dev/urandom, but yell
if this breaks the build on your exotic platform because it lacks
/dev/urandom.)

ok apb

diffstat:

 sbin/gpt/gpt_uuid.c |  124 ++++++++++++---------------------------------------
 1 files changed, 30 insertions(+), 94 deletions(-)

diffs (159 lines):

diff -r dbd90c7963ac -r a6d202e0887f sbin/gpt/gpt_uuid.c
--- a/sbin/gpt/gpt_uuid.c       Sat Oct 04 07:15:54 2014 +0000
+++ b/sbin/gpt/gpt_uuid.c       Sat Oct 04 10:30:13 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: gpt_uuid.c,v 1.7 2014/10/03 20:30:06 christos Exp $    */
+/*     $NetBSD: gpt_uuid.c,v 1.8 2014/10/04 10:30:13 riastradh Exp $   */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -32,10 +32,13 @@
 
 #include <sys/cdefs.h>
 #ifdef __RCSID
-__RCSID("$NetBSD: gpt_uuid.c,v 1.7 2014/10/03 20:30:06 christos Exp $");
+__RCSID("$NetBSD: gpt_uuid.c,v 1.8 2014/10/04 10:30:13 riastradh Exp $");
 #endif
 
+#include <err.h>
+#include <fcntl.h>
 #include <stdio.h>
+#include <unistd.h>
 
 #include "map.h"
 #include "gpt.h"
@@ -56,12 +59,6 @@
        uint8_t         node[6];
 };
 
-struct kern_uuid {
-       uint64_t        ll;
-       uint16_t        seq;
-       uint8_t         node[6];
-};
-
 static const struct {
        struct dce_uuid u;
        const char *n;
@@ -238,96 +235,35 @@
                utf8_to_utf16((const uint8_t *)gpt_nv[t].d, b, s / sizeof(*b));
 }
 
-#if !defined(HAVE_NBTOOL_CONFIG_H)
-#include <sys/types.h>
-#include <sys/uuid.h>
-#else
-#include <time.h>
-/*
- * Get the current time as a 5x bit count of 100000-microsecond intervals
- * since 00:00:00.00, October 15,1582. We apply a magic offset to convert
- * the Unix time since 00:00:00.00, January 1, 1970 to the date of the
- * Gregorian reform to the Christian calendar.
- */
-static uint64_t
-uuid_time(void)
-{
-       struct timeval tv;
-       uint64_t xtime = 0x01B21DD213814000LL;
-
-       (void)gettimeofday(&tv, NULL);
-       xtime += (uint64_t)tv.tv_sec * 10000000LL;
-       xtime += (uint64_t)(tv.tv_usec / 100000);
-       return (xtime & ((1LL << 60) - 1LL));
-}
-
-/*
- * No portable way to get ethernet, use hostid instead
- */
-static void
-uuid_node(uint8_t node[6])
-{
-       long hid = gethostid();
-       node[0] = 'N';
-       node[1] = 'B';
-       node[2] = (hid >> 24) & 0xff;
-       node[3] = (hid >> 16) & 0xff;
-       node[4] = (hid >>  8) & 0xff;
-       node[5] = (hid >>  0) & 0xff;
-}
-
-static void
-uuid_generate(void *u, uint64_t *timep, int count)
-{
-       static struct kern_uuid uuid_last;
-       uint64_t xtime, ltime;
-       uint16_t lseq;
-       struct kern_uuid *uuid = u;
-
-       uuid_node(uuid->node);
-       xtime = uuid_time();
-       *timep = xtime;
-
-       if (uuid_last.ll == 0LL || uuid_last.node[0] != uuid->node[0] ||
-           uuid_last.node[1] != uuid->node[1] ||
-           uuid_last.node[2] != uuid->node[2]) {
-               srandom((unsigned int) xtime);
-               uuid->seq = (uint16_t)random() & 0x3fff;
-       } else if (uuid_last.ll >= xtime)
-               uuid->seq = (uuid_last.seq + 1) & 0x3fff;
-
-       uuid_last = *uuid;
-       uuid_last.ll = (xtime + count - 1) & ((1LL << 60) - 1LL);
-}
-
-static void
-uuidgen(struct dce_uuid *store, int count)
-{
-       uint64_t xtime;
-       struct kern_uuid uuid;
-       int i;
-
-       /* Generate the base UUID. */
-       uuid_generate(&uuid, &xtime, count);
-
-       for (i = 0; i < count; xtime++, i++) {
-               /* Set time and version (=1) and deal with byte order. */
-               store[i].time_low = (uint32_t)xtime;
-               store[i].time_mid = (uint16_t)(xtime >> 32);
-               store[i].time_hi_and_version =
-                   ((uint16_t)(xtime >> 48) & 0xfff) | (1 << 12);
-               store[i].clock_seq_hi_and_reserved = (uuid.seq >> 16) | 0x80;
-               store[i].clock_seq_low = uuid.seq & 0xff;
-               memcpy(store[i].node, uuid.node, sizeof(uuid.node));
-       }
-}
-#endif
-
 void
 gpt_uuid_generate(gpt_uuid_t t)
 {
        struct dce_uuid u;
+       int fd;
+       uint8_t *p;
+       size_t n;
+       ssize_t nread;
 
-       uuidgen((void *)&u, 1);
+       /* Randomly generate the content.  */
+       fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
+       if (fd == -1)
+               err(1, "open(/dev/urandom)");
+       for (p = (void *)&u, n = sizeof u; 0 < n; p += nread, n -= nread) {
+               nread = read(fd, p, n);
+               if (nread < 0)
+                       err(1, "read(/dev/urandom)");
+               if ((size_t)nread > n)
+                       errx(1, "read too much: %zd > %zu", nread, n);
+       }
+       (void)close(fd);
+
+       /* Set the version number to 4.  */
+       u.time_hi_and_version &= ~(uint32_t)0xf000;
+       u.time_hi_and_version |= 0x4000;
+
+       /* Fix the reserved bits.  */
+       u.clock_seq_hi_and_reserved &= ~(uint8_t)0x40;
+       u.clock_seq_hi_and_reserved |= 0x80;
+
        gpt_dce_to_uuid(&u, t);
 }



Home | Main Index | Thread Index | Old Index