Skip to contentSkip to conversation

Add generic function to read /dev/urandom, used in uuid calculation.

PATCH New Dave Wysochanski 2 participants 3 messages Dec 6, 2008 Library code

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 Add generic function to read /dev/urandom, used in uuid calculation.

---
 include/.symlinks |    1 +
 lib/Makefile.in   |    1 +
 lib/misc/random.c |   29 +++++++++++++++++++++++++++++
 lib/misc/random.h |   20 ++++++++++++++++++++
 lib/uuid/uuid.c   |   14 ++------------
 5 files changed, 53 insertions(+), 12 deletions(-)
 create mode 100644 lib/misc/random.c
 create mode 100644 lib/misc/random.h
include/.symlinks +1 -0
index b70b96d..9039f67 100644
@@ -47,6 +47,7 @@
 ../lib/misc/lvm-globals.h
 ../lib/misc/lvm-string.h
 ../lib/misc/lvm-wrappers.h
+../lib/misc/random.h
 ../lib/misc/sharedlib.h
 ../lib/report/report.h
 ../lib/uuid/uuid.h
lib/Makefile.in +1 -0
index 54092cd..71f98d7 100644
@@ -80,6 +80,7 @@ SOURCES =\
 	misc/lvm-globals.c \
 	misc/lvm-string.c \
 	misc/lvm-wrappers.c \
+	misc/random.c \
 	misc/timestamp.c \
 	misc/util.c \
 	mm/memlock.c \
lib/misc/random.c new file +29 -0
new file mode 100644
index 0000000..8ebfb89
@@ -0,0 +1,29 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "lib.h"
+#include "random.h"
+
+int read_urandom(void *buf, size_t len)
+{
+	int fd;
+
+	if ((fd = open("/dev/urandom", O_RDONLY)) < 0) {
+		log_sys_error("open", "get_random: /dev/urandom");
+		return 0;
+	}
+
+	if (read(fd, buf, len) != (ssize_t) len) {
+		log_sys_error("read", "get_random: /dev/urandom");
+		if (close(fd))
+			stack;
+		return 0;
+	}
+
+	if (close(fd))
+		stack;
+
+	return 1;
+}
+
lib/misc/random.h new file +20 -0
new file mode 100644
index 0000000..1347fdd
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _LVM_RANDOM_H
+#define _LVM_RANDOM_H
+
+int read_urandom(void *buf, size_t len);
+
+#endif
lib/uuid/uuid.c +2 -12
index 39252c0..5069d1d 100644
@@ -15,6 +15,7 @@
 
 #include "lib.h"
 #include "uuid.h"
+#include "random.h"
 
 #include <assert.h>
 #include <sys/stat.h>
@@ -94,25 +95,14 @@ int lvid_in_restricted_range(union lvid *lvid)
 
 int id_create(struct id *id)
 {
-	int randomfile;
 	unsigned i;
 	size_t len = sizeof(id->uuid);
 
 	memset(id->uuid, 0, len);
-	if ((randomfile = open("/dev/urandom", O_RDONLY)) < 0) {
-		log_sys_error("open", "id_create: /dev/urandom");
+	if (!read_urandom(&id->uuid, len)) {
 		return 0;
 	}
 
-	if (read(randomfile, id->uuid, len) != (ssize_t) len) {
-		log_sys_error("read", "id_create: /dev/urandom");
-		if (close(randomfile))
-			stack;
-		return 0;
-	}
-	if (close(randomfile))
-		stack;
-
 	/*
 	 * Skip out the last 2 chars in randomized creation for LVM1
 	 * backwards compatibility.
Signature · 1 line
1.5.5.1
#1 lore raw

PATCH 2/2 Make _init_rand() thread safe - use rand_r() instead of rand().

Use good entropy for seed value if possible.

---
 lib/commands/toolcontext.c    |   10 ++++++++++
 lib/commands/toolcontext.h    |    1 +
 lib/format_text/archive.c     |    3 ++-
 lib/format_text/format-text.c |    3 ++-
 lib/misc/lvm-file.c           |    5 +++--
 lib/misc/lvm-file.h           |    3 ++-
 tools/lvmcmdline.c            |    7 -------
 7 files changed, 20 insertions(+), 12 deletions(-)
lib/commands/toolcontext.c +10 -0
index f49c7c6..a987469 100644
@@ -979,6 +979,14 @@ static int _init_backup(struct cmd_context *cmd)
 	return 1;
 }
 
+static void _init_rand(struct cmd_context *cmd)
+{
+	if (read_urandom(&cmd->rand_seed, sizeof(cmd->rand_seed)))
+		return;
+
+	cmd->rand_seed = (unsigned) time(NULL) + (unsigned) getpid();
+}
+
 /* Entry point */
 struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static,
 				       unsigned is_long_lived)
@@ -1077,6 +1085,8 @@ struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static,
 	if (!_init_backup(cmd))
 		goto error;
 
+	_init_rand(cmd);
+
 	cmd->default_settings.cache_vgmetadata = 1;
 	cmd->current_settings = cmd->default_settings;
 
lib/commands/toolcontext.h +1 -0
index 6cbf6a6..4ea3486 100644
@@ -62,6 +62,7 @@ struct cmd_context {
 	const char *hostname;
 	const char *kernel_vsn;
 
+	unsigned rand_seed;
 	char *cmd_line;
 	struct command *command;
 	struct arg *args;
lib/format_text/archive.c +2 -1
index b232db7..3e5b0c4 100644
@@ -236,7 +236,8 @@ int archive_vg(struct volume_group *vg,
 	/*
 	 * Write the vg out to a temporary file.
 	 */
-	if (!create_temp_name(dir, temp_file, sizeof(temp_file), &fd)) {
+	if (!create_temp_name(dir, temp_file, sizeof(temp_file), &fd,
+			      &vg->cmd->rand_seed)) {
 		log_err("Couldn't create temporary archive name.");
 		return 0;
 	}
lib/format_text/format-text.c +2 -1
index fc4e5ff..af9c2ac 100644
@@ -848,7 +848,8 @@ static int _vg_write_file(struct format_instance *fid __attribute((unused)),
 		return 0;
 	}
 
-	if (!create_temp_name(temp_dir, temp_file, sizeof(temp_file), &fd)) {
+	if (!create_temp_name(temp_dir, temp_file, sizeof(temp_file), &fd,
+			      &vg->cmd->rand_seed)) {
 		log_err("Couldn't create temporary text file name.");
 		return 0;
 	}
lib/misc/lvm-file.c +3 -2
index 3e812d1..a5a5f2b 100644
@@ -29,7 +29,8 @@
  * rename the file after successfully writing it.  Grab
  * NFS-supported exclusive fcntl discretionary lock.
  */
-int create_temp_name(const char *dir, char *buffer, size_t len, int *fd)
+int create_temp_name(const char *dir, char *buffer, size_t len, int *fd,
+		     unsigned *seed)
 {
 	int i, num;
 	pid_t pid;
@@ -41,7 +42,7 @@ int create_temp_name(const char *dir, char *buffer, size_t len, int *fd)
 		.l_len = 0
 	};
 
-	num = rand();
+	num = rand_r(seed);
 	pid = getpid();
 	if (gethostname(hostname, sizeof(hostname)) < 0) {
 		log_sys_error("gethostname", "");
lib/misc/lvm-file.h +2 -1
index 8110be1..07327c3 100644
@@ -19,7 +19,8 @@
 /*
  * Create a temporary filename, and opens a descriptor to the file.
  */
-int create_temp_name(const char *dir, char *buffer, size_t len, int *fd);
+int create_temp_name(const char *dir, char *buffer, size_t len, int *fd,
+		     unsigned *seed);
 
 /*
  * NFS-safe rename of a temporary file to a common name, designed
tools/lvmcmdline.c +0 -7
index 78e9e60..29b4c15 100644
@@ -997,11 +997,6 @@ int lvm_split(char *str, int *argc, char **argv, int max)
 	return *argc;
 }
 
-static void _init_rand(void)
-{
-	srand((unsigned) time(NULL) + (unsigned) getpid());
-}
-
 static const char *_get_cmdline(pid_t pid)
 {
 	static char _proc_cmdline[32];
@@ -1096,8 +1091,6 @@ struct cmd_context *init_lvm(unsigned is_static)
 	if (!(cmd = create_toolcontext(_cmdline.the_args, is_static, 0)))
 		return_NULL;
 
-	_init_rand();
-
 	_apply_settings(cmd);
 
 	return cmd;
Signature · 1 line
1.5.5.1
#2 lore raw

PATCH 1/2 Add generic function to read /dev/urandom, used in uuid calculation.

In reply to Dave Wysochanski

lib/Makefile.in SOURCES =\ · line 85

Quoted 9 lines · Dave Wysochanski
lib/Makefile.in +1 -0
@@ -80,6 +80,7 @@ SOURCES =\
 	misc/lvm-globals.c \
 	misc/lvm-string.c \
 	misc/lvm-wrappers.c \
+	misc/random.c \
 	misc/timestamp.c \
 	misc/util.c \

For the newer files I've been using an lvm- prefix.
But rather than adding a new file, just add it to either lvm-file.c (it's doing file manipulation) or lvm-wrappers.c (it's wrapping a random number generating function).

lib/Makefile.in SOURCES =\

Quoted 4 lines
lib/Makefile.in +4 -0
+	if ((fd = open("/dev/urandom", O_RDONLY)) < 0) {
+		log_sys_error("open", "get_random: /dev/urandom");
+		return 0;
+	}

(strictly we should stat it first and have a fallback if it doesn't exist - a FIXME to suggest that? Not worth coding though till someone actually needs it.)

lib/Makefile.in

Quoted 6 lines
lib/Makefile.in +6 -0
+	if (read(fd, buf, len) != (ssize_t) len) {
+		log_sys_error("read", "get_random: /dev/urandom");
+		if (close(fd))
+			stack;
+		return 0;
+	}

Again, a FIXME to handle the standard complexity of read()? (Ideally we'd push this through the existing _io() function instead of having another less-well-implemented open...read...close sequence.)

Alasdair

Signature · 1 line
agk at redhat.com