summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/nvmutil/nvmutil.c133
1 files changed, 73 insertions, 60 deletions
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c
index 91095c18..5401c2eb 100644
--- a/util/nvmutil/nvmutil.c
+++ b/util/nvmutil/nvmutil.c
@@ -373,8 +373,7 @@ void set_mac_byte(unsigned long mac_byte_pos);
void set_mac_nib(unsigned long mac_str_pos,
unsigned long mac_byte_pos, unsigned long mac_nib_pos);
unsigned short hextonum(char ch_s);
-unsigned short rhex(void);
-unsigned short read_urandom(void);
+unsigned long rlong(void);
unsigned long entropy_jitter(void);
int x_i_gettimeofday(struct x_st_timeval *tv, void *tz);
void write_mac_part(unsigned long partnum);
@@ -472,7 +471,13 @@ const char *getnvmprogname(void);
char *new_tmpfile(int *fd, int local, const char *path);
int x_i_mkstemp(char *template);
char *x_c_strrchr(const char *s, int c);
+/* x_i_rename not suitable
+ * for atomic writes. kept
+ * commentted for use in a
+ * library in the future */
+/*
int x_i_rename(const char *src, const char *dst);
+*/
char *x_c_tmpdir(void);
int x_i_close(int fd);
void *x_v_memcpy(void *dst,
@@ -717,10 +722,6 @@ char *tname = NULL;
#endif
#endif
-#ifndef S_ISREG
-#define S_ISREG(m) (((m) & (S_IFMT) == (S_IFREG))
-#endif
-
int
main(int argc, char *argv[])
{
@@ -995,8 +996,8 @@ open_gbe_file(void)
gbe_ino = gbe_st.st_ino;
if (gbe_st.st_nlink > 1)
- fprintf(stderr,
- "%s: warning: file has %lu hard links\n",
+ err(EINVAL,
+ "%s: warning: file has multiple (%lu) hard links\n",
fname, (unsigned long)gbe_st.st_nlink);
if (gbe_st.st_nlink == 0)
@@ -1362,30 +1363,25 @@ hextonum(char ch_s)
return ch - 'a' + 10;
if (ch == '?' || ch == 'x')
- return rhex(); /* random character */
+ return (unsigned short)rlong() & 0xf;
return 16; /* invalid character */
}
-unsigned short
-rhex(void)
+unsigned long
+rlong(void)
{
struct x_st_timeval tv;
- unsigned long mix;
+ static unsigned long mix = 0;
static unsigned long counter = 0;
- unsigned short r;
- /* Read /dev/urandom
- * if possible */
- r = read_urandom();
- if (r < 16)
- return r;
-
- /* Fallback */
+ static int fd = -1;
+ unsigned long rval = 0;
+ long nr = -1;
x_i_gettimeofday(&tv, NULL);
- mix = (unsigned long)tv.tv_sec
+ mix ^= (unsigned long)tv.tv_sec
^ (unsigned long)tv.tv_usec
^ (unsigned long)getpid()
^ (unsigned long)&mix
@@ -1400,45 +1396,45 @@ rhex(void)
mix ^= (unsigned long)&tv;
mix ^= (unsigned long)&counter;
- return (unsigned short)(mix & 0xf);
-}
-
-unsigned short
-read_urandom(void)
-{
- static int fd = -1;
- static long n = -1;
-
- static unsigned char r[256];
+ /*
+ * Now, we won't use this mix
+ * immediately. We'll try to
+ * read urandom first, which is
+ * likely safer, and pass that,
+ * falling back to the mixture
+ * if urandom fails.
+ *
+ * Since urandom is likely
+ * reliable, the number of
+ * times it will fail is
+ * likely extremely random,
+ * thus, building more than
+ * sufficient entropy by the
+ * time we do eventually use
+ * the fallback code
+ */
- if (fd < 0) {
+ if (fd < 0)
+ fd = open("/dev/urandom", O_RDONLY | O_BINARY | O_NONBLOCK);
- fd = open("/dev/urandom", O_RDONLY | O_NONBLOCK);
-#ifndef NVMUTIL_UNVEIL
- if (fd < 0) /* older openbsd */
- fd = open("/dev/arandom", O_RDONLY | O_NONBLOCK);
+#if !(defined(__OpenBSD__) && defined(OpenBSD)) || \
+ (defined(__OpenBSD__) && defined(OpenBSD) && \
+ OpenBSD < 604)
+ if (fd < 0) /* old openbsd */
+ fd = open("/dev/arandom", O_RDONLY | O_BINARY | O_NONBLOCK);
#endif
- if (fd < 0) /* super old unix (could block) */
- fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
- if (fd < 0)
- return 16;
- }
-
- if (n < 0) {
-
- n = rw_file_exact(fd, r, 256, 0, IO_READ,
- LOOP_EAGAIN, LOOP_EINTR, 2, OFF_ERR);
+ if (fd < 0)
+ fd = open("/dev/random", O_RDONLY | O_BINARY | O_NONBLOCK);
- if (n == 0)
- n = -1;
- if (n < 0)
- return 16;
+ nr = rw_file_exact(fd, (unsigned char *)&rval,
+ sizeof(unsigned long), 0, IO_READ, LOOP_EAGAIN,
+ LOOP_EINTR, MAX_ZERO_RW_RETRY, OFF_ERR);
- --n;
- }
+ if (nr == sizeof(unsigned long))
+ return rval;
- return r[n--] & 0xf;
+ return mix;
}
unsigned long
@@ -1449,8 +1445,9 @@ entropy_jitter(void)
long mix_diff;
int i;
+ x_i_gettimeofday(&a, NULL);
+
for (i = 0; i < 8; i++) {
- x_i_gettimeofday(&a, NULL);
getpid();
x_i_gettimeofday(&b, NULL);
@@ -1481,7 +1478,7 @@ x_i_gettimeofday(struct x_st_timeval *tv, void *tz)
t = time(NULL);
tv->tv_sec = t;
- tv->tv_usec = (long)clock() % 1000000;
+ tv->tv_usec = (long)((unsigned long)clock() % 1000000UL);
return 0;
}
@@ -2003,7 +2000,7 @@ gbe_mv(void)
saved_errno = errno;
- r = x_i_rename(tname, fname);
+ r = rename(tname, fname);
if (r > -1) {
/*
@@ -2056,7 +2053,7 @@ gbe_mv(void)
if (x_i_close(dest_fd) == -1)
goto ret_gbe_mv;
- if (x_i_rename(dest_tmp, fname) == -1)
+ if (rename(dest_tmp, fname) == -1)
goto ret_gbe_mv;
if (fsync_dir(fname) < 0)
@@ -2109,7 +2106,7 @@ ret_gbe_mv:
}
/*
- * Ensure x_i_rename() is durable by syncing the
+ * Ensure rename() is durable by syncing the
* directory containing the target file.
*/
int
@@ -2138,6 +2135,12 @@ fsync_dir(const char *path)
goto err_fsync_dir;
}
+ if (pathlen == 0)
+ {
+ errno = EINVAL;
+ goto err_fsync_dir;
+ }
+
dirbuf = malloc(pathlen + 1);
if (dirbuf == NULL)
goto err_fsync_dir;
@@ -2153,7 +2156,14 @@ fsync_dir(const char *path)
strcpy(dirbuf, ".");
}
- dfd = open(dirbuf, O_RDONLY);
+ dfd = open(dirbuf, O_RDONLY
+#ifdef O_DIRECTORY
+ | O_DIRECTORY
+#endif
+#ifdef O_NOFOLLOW
+ | O_NOFOLLOW
+#endif
+ );
if (dfd == -1)
goto err_fsync_dir;
@@ -3029,6 +3039,7 @@ x_i_mkstemp(char *template)
char *p;
char ch[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ unsigned long r = rlong();
len = xstrxlen(template, PATH_LEN);
@@ -3041,7 +3052,7 @@ x_i_mkstemp(char *template)
for (i = 0; i < 100; i++) {
for (j = 0; j < 6; j++)
- p[j] = ch[rhex() & 31];
+ p[j] = ch[r % (sizeof(ch) - 1)];
fd = open(template, O_RDWR | O_CREAT | O_EXCL, 0600);
@@ -3073,6 +3084,7 @@ x_c_strrchr(const char *s, int c)
return (char *)p;
}
+/*
int
x_i_rename(const char *src, const char *dst)
{
@@ -3115,6 +3127,7 @@ x_i_rename(const char *src, const char *dst)
return 0;
}
+*/
char *
x_c_tmpdir(void)