diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 684f06cd4f..8bb78d9502 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2094,6 +2094,7 @@ virProcessWait; # util/virrandom.h virRandom; virRandomBits; +virRandomBytes; virRandomGenerateWWN; virRandomInt; diff --git a/src/util/virrandom.c b/src/util/virrandom.c index 67a8bd0554..62a0e314e6 100644 --- a/src/util/virrandom.c +++ b/src/util/virrandom.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2015 Red Hat, Inc. + * Copyright (C) 2012-2016 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 @@ -26,12 +26,16 @@ #include #include #include +#include +#include +#include #include "virrandom.h" #include "virthread.h" #include "count-one-bits.h" #include "virutil.h" #include "virerror.h" +#include "virfile.h" #include "virlog.h" #include "virstring.h" @@ -156,11 +160,49 @@ uint32_t virRandomInt(uint32_t max) } +/** + * virRandomBytes + * @buf: Pointer to location to store bytes + * @buflen: Number of bytes to store + * + * Generate a stream of random bytes from /dev/urandom + * into @buf of size @buflen + */ +int +virRandomBytes(unsigned char *buf, + size_t buflen) +{ + int fd; + + if ((fd = open("/dev/urandom", O_RDONLY)) < 0) + return errno; + + while (buflen > 0) { + ssize_t n; + + if ((n = read(fd, buf, buflen)) <= 0) { + if (errno == EINTR) + continue; + VIR_FORCE_CLOSE(fd); + return n < 0 ? errno : ENODATA; + } + + buf += n; + buflen -= n; + } + + VIR_FORCE_CLOSE(fd); + + return 0; +} + + #define QUMRANET_OUI "001a4a" #define VMWARE_OUI "000569" #define MICROSOFT_OUI "0050f2" #define XEN_OUI "00163e" + int virRandomGenerateWWN(char **wwn, const char *virt_type) diff --git a/src/util/virrandom.h b/src/util/virrandom.h index 769df94c44..f457d2de66 100644 --- a/src/util/virrandom.h +++ b/src/util/virrandom.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Red Hat, Inc. + * Copyright (C) 2012, 2016 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 @@ -27,6 +27,8 @@ uint64_t virRandomBits(int nbits); double virRandom(void); uint32_t virRandomInt(uint32_t max); +int virRandomBytes(unsigned char *buf, size_t buflen) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; int virRandomGenerateWWN(char **wwn, const char *virt_type); #endif /* __VIR_RANDOM_H__ */ diff --git a/src/util/viruuid.c b/src/util/viruuid.c index 615d419e03..1fcc95405b 100644 --- a/src/util/viruuid.c +++ b/src/util/viruuid.c @@ -52,34 +52,6 @@ VIR_LOG_INIT("util.uuid"); static unsigned char host_uuid[VIR_UUID_BUFLEN]; -static int -virUUIDGenerateRandomBytes(unsigned char *buf, - int buflen) -{ - int fd; - - if ((fd = open("/dev/urandom", O_RDONLY)) < 0) - return errno; - - while (buflen > 0) { - int n; - - if ((n = read(fd, buf, buflen)) <= 0) { - if (errno == EINTR) - continue; - VIR_FORCE_CLOSE(fd); - return n < 0 ? errno : ENODATA; - } - - buf += n; - buflen -= n; - } - - VIR_FORCE_CLOSE(fd); - - return 0; -} - static int virUUIDGeneratePseudoRandomBytes(unsigned char *buf, int buflen) @@ -108,7 +80,7 @@ virUUIDGenerate(unsigned char *uuid) if (uuid == NULL) return -1; - if ((err = virUUIDGenerateRandomBytes(uuid, VIR_UUID_BUFLEN))) { + if ((err = virRandomBytes(uuid, VIR_UUID_BUFLEN))) { char ebuf[1024]; VIR_WARN("Falling back to pseudorandom UUID," " failed to generate random bytes: %s",