summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/nvmutil/nvmutil.c94
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;