diff options
| -rw-r--r-- | util/nvmutil/nvmutil.c | 94 |
1 files changed, 56 insertions, 38 deletions
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c index a03af5e4..c6193d9e 100644 --- a/util/nvmutil/nvmutil.c +++ b/util/nvmutil/nvmutil.c @@ -50,7 +50,7 @@ static void read_file_exact(int fd, void *buf, size_t len, off_t off, const char *path, const char *op); static int write_mac_part(size_t partnum); static void cmd_dump(void); -static void print_mac_address(size_t partnum); +static void print_mac_from_nvm(size_t partnum); static void hexdump(size_t partnum); static void cmd_setchecksum(void); static void set_checksum(size_t part); @@ -147,8 +147,17 @@ static const char rmac[] = "xx:xx:xx:xx:xx:xx"; static const char *fname; static const char *argv0; +#define PART_INVERT 1 +#define NO_INVERT 0 +#define ARGC_3 3 +#define ARGC_4 4 + /* * Used as indices for command[] + * + * MUST be in the same order as entries in + * command[] - or run_cmd() will detect this, + * and cause a non-zero exit (err). */ enum { CMD_DUMP, @@ -160,34 +169,31 @@ enum { }; #define CMD_NULL -1 -/* - * Those enum values are used for .chk in - * the command struct. Then, even if an index - * is valid, if it doesn't match .chk, run_cmd() - * will fail. This mitigates against the possibility - * of a maintainer (read: you) screwing up the enum, - * which otherwise enables easier understanding. - * - * In other words: the order of the CMD enum must - * precisely match the order of the command struct. - */ struct commands { size_t chk; /* use by in later check on run_cmd, against cmd index, to verify correct enum order */ const char *str; void (*run)(void); - int args; + int argc; uint8_t invert; }; + +/* + * Pointers used for running nvmutil commands + */ static const struct commands command[] = { - { CMD_DUMP, "dump", cmd_dump, 3, 0 }, - { CMD_SETMAC, "setmac", cmd_setmac, 3, 0 }, - { CMD_SWAP, "swap", cmd_swap, 3, 1 }, - { CMD_COPY, "copy", cmd_copy, 4, 1 }, - { CMD_BRICK, "brick", cmd_brick, 4, 0 }, - { CMD_SETCHECKSUM, "setchecksum", cmd_setchecksum, 4, 0 }, + { CMD_DUMP, "dump", cmd_dump, ARGC_3, NO_INVERT }, + { CMD_SETMAC, "setmac", cmd_setmac, ARGC_3, NO_INVERT }, + { CMD_SWAP, "swap", cmd_swap, ARGC_3, PART_INVERT }, + { CMD_COPY, "copy", cmd_copy, ARGC_4, PART_INVERT }, + { CMD_BRICK, "brick", cmd_brick, ARGC_4, NO_INVERT }, + { CMD_SETCHECKSUM, "setchecksum", cmd_setchecksum, + ARGC_4, NO_INVERT }, }; +/* + * Index in command[], will be set later + */ static ssize_t cmd = CMD_NULL; int @@ -206,18 +212,16 @@ main(int argc, char *argv[]) /* * For restricted filesystem access on early error. * - * Unveiling the random device early, regardless of - * whether we will use it, prevents operations on any - * GbE files until we permit it, while performing the - * prerequisite error checks. + * This prevents access to /dev/urandom, which we + * should never use in OpenBSD (we use arc4random), + * thus guarding against any future bugs there. * - * We don't actually use the random device on platforms - * that have arc4random, which includes OpenBSD. + * This also prevents early reads to the GbE file, + * while performing other checks; we will later + * unveil the GbE file, to allow access. */ - if (unveil("/dev/urandom", "r") == -1) - err(ECANCELED, "unveil '/dev/urandom'"); - if (unveil("/dev/random", "r") == -1) - err(ECANCELED, "unveil '/dev/random'"); + if (unveil("/dev/null", "r") == -1) + err(ECANCELED, "unveil '/dev/null'"); #endif set_cmd(argc, argv); @@ -242,8 +246,12 @@ main(int argc, char *argv[]) } #endif -#ifndef HAVE_ARC4RANDOM_BUF - open_dev_urandom(); +#ifdef HAVE_ARC4RANDOM_BUF + if (cmd == CMD_SETMAC) + printf("Randomisation method: arc4random_buf\n"); +#else + if (cmd == CMD_SETMAC) + open_dev_urandom(); #endif open_gbe_file(); @@ -259,8 +267,10 @@ main(int argc, char *argv[]) if (close(gbe_fd) == -1) err(ECANCELED, "close '%s'", fname); #ifndef HAVE_ARC4RANDOM_BUF - if (close(urandom_fd) == -1) - err(ECANCELED, "close '%s'", rname); + if (urandom_fd > -1) { + if (close(urandom_fd) == -1) + err(ECANCELED, "close '%s'", rname); + } #endif /* @@ -306,7 +316,7 @@ set_cmd(int argc, char *argv[]) for (cmd = 0; cmd < (ssize_t)items(command); cmd++) { if (strcmp(argv[2], command[cmd].str) != 0) continue; - if (argc >= command[cmd].args) { + if (argc >= command[cmd].argc) { return; } @@ -326,7 +336,7 @@ check_cmd_args(int argc, char *argv[]) */ mac_str = argv[2]; cmd = CMD_SETMAC; - } else if (cmd == CMD_SETMAC) { /* 1 is setmac */ + } else if (cmd == CMD_SETMAC) { /* * Example: ./nvmutil gbe.bin setmac xx:1f:16:xx:xx:xx */ @@ -398,6 +408,8 @@ open_dev_urandom(void) { struct stat st_urandom_fd; + printf("Randomisation method: %s\n", newrandom); + /* * Try /dev/urandom first */ @@ -405,6 +417,9 @@ open_dev_urandom(void) if ((urandom_fd = open(rname, O_RDONLY)) != -1) return; + fprintf(stderr, "Can't open %s (will use %s instead)\n", + newrandom, oldrandom); + /* * Fall back to /dev/random on old platforms * where /dev/urandom does not exist. @@ -615,6 +630,9 @@ read_file_exact(int fd, void *buf, size_t len, int retry; ssize_t rval; + if (fd == -1) + err(ECANCELED, "Trying to open bad fd: %s", path); + for (retry = 0; retry < MAX_RETRY_READ; retry++) { if (op) rval = pread(fd, buf, len, off); @@ -653,7 +671,7 @@ write_mac_part(size_t partnum) set_word(w, partnum, mac_buf[w]); printf("Wrote MAC address to part %zu: ", partnum); - print_mac_address(partnum); + print_mac_from_nvm(partnum); set_checksum(partnum); @@ -671,7 +689,7 @@ cmd_dump(void) ++num_invalid; printf("MAC (part %zu): ", partnum); - print_mac_address(partnum); + print_mac_from_nvm(partnum); hexdump(partnum); } @@ -680,7 +698,7 @@ cmd_dump(void) } static void -print_mac_address(size_t partnum) +print_mac_from_nvm(size_t partnum) { size_t c; |
