diff options
| -rw-r--r-- | util/nvmutil/nvmutil.c | 133 |
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) |
