diff options
Diffstat (limited to 'util/nvmutil')
| -rw-r--r-- | util/nvmutil/nvmutil.c | 121 |
1 files changed, 57 insertions, 64 deletions
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c index f86e88bf..7c0d0c31 100644 --- a/util/nvmutil/nvmutil.c +++ b/util/nvmutil/nvmutil.c @@ -20,15 +20,12 @@ void cmd_setchecksum(void), cmd_brick(void), swap(int partnum), writeGbe(void), parseMacString(const char *strMac, uint16_t *mac), cmd_swap(void), openFiles(const char *path), cmd_copy(void), writeGbe_part(int), readGbe_part(int), usage(char*), set_io_flags(int, char **), - set_cmd(int, char **), setWord(int, int, uint16_t), check_bounds(int, int); + set_cmd(int, char **), setWord(int, int, uint16_t), check_bounds(int, int), + xopen (int *, const char *, int p, struct stat *); int goodChecksum(int partnum); uint8_t hextonum(char chs), rhex(void); uint16_t word(int, int); -#ifdef __OpenBSD__ -void block_unveil(void); -#endif - #define COMMAND argv[2] #define MAC_ADDRESS argv[3] #define PARTN argv[3] @@ -43,10 +40,10 @@ void block_unveil(void); uint16_t mac[3] = {0, 0, 0}; ssize_t nf; -size_t partsize, gbe[2]; +size_t partsize; +uint8_t *gbe[2]; uint8_t nvmPartChanged[2] = {0, 0}, do_read[2] = {1, 1}; int flags, rfd, fd, part, e = 1; -struct stat st; const char *strMac = NULL, *strRMac = "xx:xx:xx:xx:xx:xx", *fname = NULL; @@ -56,23 +53,17 @@ typedef struct op { int args; } op_t; op_t op[] = { -{ .str = "dump", .cmd = cmd_dump, .args = 3}, -{ .str = "setmac", .cmd = cmd_setmac, .args = 3}, -{ .str = "swap", .cmd = cmd_swap, .args = 3}, -{ .str = "copy", .cmd = cmd_copy, .args = 4}, -{ .str = "brick", .cmd = cmd_brick, .args = 4}, -{ .str = "setchecksum", .cmd = cmd_setchecksum, .args = 4}, +{ .str = "dump", .cmd = cmd_dump, .args = 3 }, +{ .str = "setmac", .cmd = cmd_setmac, .args = 3 }, +{ .str = "swap", .cmd = cmd_swap, .args = 3 }, +{ .str = "copy", .cmd = cmd_copy, .args = 4 }, +{ .str = "brick", .cmd = cmd_brick, .args = 4 }, +{ .str = "setchecksum", .cmd = cmd_setchecksum, .args = 4 }, }; void (*cmd)(void) = NULL; -#define SET_ERR(x) errno = errno ? errno : x -#define err_if(x) if (x) err(SET_ERR(ECANCELED), "%s", fname) - -#define xopen(f,l,p) \ - if ((f = open(l, p)) == -1) \ - err(SET_ERR(ECANCELED), "%s", l); \ - if (fstat(f, &st) == -1) \ - err(SET_ERR(ECANCELED), "%s", l) +#define set_err(x) errno = errno ? errno : x +#define err_if(x) if (x) err(set_err(ECANCELED), "%s", fname) int main(int argc, char *argv[]) @@ -86,13 +77,20 @@ main(int argc, char *argv[]) fname = argv[1]; set_io_flags(argc, argv); #ifdef __OpenBSD__ - block_unveil(); + if (flags == O_RDONLY) { + err_if(unveil(fname, "r") == -1); + err_if(unveil(NULL, NULL) == -1); + err_if(pledge("stdio rpath", NULL) == -1); + } else { + err_if(unveil(fname, "rw") == -1); + err_if(unveil(NULL, NULL) == -1); + err_if(pledge("stdio rpath wpath", NULL) == -1); + } #endif openFiles(fname); #ifdef __OpenBSD__ err_if(pledge("stdio", NULL) == -1); #endif - nvmalloc(); readGbe(); (*cmd)(); @@ -115,7 +113,7 @@ set_cmd(int argc, char *argv[]) cmd = op[i].cmd; break; } - err(SET_ERR(EINVAL), "Too few args on command '%s'", + err(set_err(EINVAL), "Too few args on command '%s'", op[i].str); } } else { /* argc == 2 */ @@ -149,7 +147,7 @@ void checkdir(const char *path) { if (opendir(path) != NULL) - err(SET_ERR(EISDIR), "%s", path); + err(set_err(EISDIR), "%s", path); if (errno == ENOTDIR) errno = 0; err_if(errno); @@ -158,11 +156,13 @@ checkdir(const char *path) void openFiles(const char *path) { + struct stat st; + checkdir("/dev/urandom"); checkdir(fname); - xopen(rfd, "/dev/urandom", O_RDONLY); - xopen(fd, path, flags); + xopen(&rfd, "/dev/urandom", O_RDONLY, &st); + xopen(&fd, path, flags, &st); switch(st.st_size) { case SIZE_8KB: @@ -171,12 +171,21 @@ openFiles(const char *path) partsize = st.st_size >> 1; break; default: - err(SET_ERR(ECANCELED), "Invalid file size (not 8/16/128KiB)"); + err(set_err(ECANCELED), "Invalid file size (not 8/16/128KiB)"); break; } } void +xopen(int *f, const char *l, int p, struct stat *st) +{ + if ((*f = open(l, p)) == -1) \ + err(set_err(ECANCELED), "%s", l); \ + if (fstat(*f, st) == -1) \ + err(set_err(ECANCELED), "%s", l); +} + +void nvmalloc(void) { /* same operations need the full block, others only 128 bytes */ @@ -189,11 +198,11 @@ nvmalloc(void) do_read[part ^ 1] = 0; /* only allocate one block if only one part being read */ - char *buf = malloc(nf << (do_read[0] & do_read[1])); + uint8_t *buf = (uint8_t *) malloc(nf << (do_read[0] & do_read[1])); if (buf == NULL) err(errno, NULL); - gbe[0] = (size_t) buf; + gbe[0] = buf; /* speedhack: for cmd copy, both pointers are set the same */ gbe[1] = gbe[0] + (nf * (do_read[0] & do_read[1])); @@ -211,7 +220,7 @@ void readGbe_part(int p) { if (pread(fd, (uint8_t *) gbe[p], nf, p * partsize) != nf) - err(SET_ERR(ECANCELED), + err(set_err(ECANCELED), "Can't read %ld b from '%s' p%d", nf, fname, p); swap(p); /* handle big-endian host CPU */ } @@ -247,12 +256,12 @@ parseMacString(const char *strMac, uint16_t *mac) { uint64_t total = 0; if (strnlen(strMac, 20) != 17) - err(SET_ERR(EINVAL), "Invalid MAC address string length"); + err(set_err(EINVAL), "Invalid MAC address string length"); for (uint8_t h, i = 0; i < 16; i += 3) { if (i != 15) if (strMac[i + 2] != ':') - err(SET_ERR(EINVAL), + err(set_err(EINVAL), "Invalid MAC address separator '%c'", strMac[i + 2]); @@ -260,7 +269,7 @@ parseMacString(const char *strMac, uint16_t *mac) for (int nib = 0; nib < 2; nib++, total += h) { if ((h = hextonum(strMac[i + nib])) > 15) - err(SET_ERR(EINVAL), "Invalid character '%c'", + err(set_err(EINVAL), "Invalid character '%c'", strMac[i + nib]); /* If random, ensure that local/unicast bits are set */ @@ -276,9 +285,9 @@ parseMacString(const char *strMac, uint16_t *mac) } if (total == 0) - err(SET_ERR(EINVAL), "Invalid MAC (all-zero MAC address)"); + err(set_err(EINVAL), "Invalid MAC (all-zero MAC address)"); if (mac[0] & 1) - err(SET_ERR(EINVAL), "Invalid MAC (multicast bit set)"); + err(set_err(EINVAL), "Invalid MAC (multicast bit set)"); } uint8_t @@ -381,9 +390,9 @@ cmd_swap(void) { err_if(!(goodChecksum(0) || goodChecksum(1))); errno = 0; - gbe[0] ^= gbe[1]; - gbe[1] ^= gbe[0]; - gbe[0] ^= gbe[1]; + uint8_t *chg = gbe[0]; + gbe[0] = gbe[1]; + gbe[1] = chg; nvmPartChanged[0] = nvmPartChanged[1] = 1; } @@ -399,7 +408,7 @@ goodChecksum(int partnum) return 1; fprintf(stderr, "WARNING: BAD checksum in part %d\n", partnum); - SET_ERR(ECANCELED); + set_err(ECANCELED); return 0; } @@ -424,9 +433,9 @@ void check_bounds(int c, int p) { if ((p != 0) && (p != 1)) - err(SET_ERR(EINVAL), "check_bounds: invalid partnum %d", p); - if ((c < 0) || (c > nf)) - err(SET_ERR(EINVAL), "check_bounds: out of bounds %d", c); + err(set_err(EINVAL), "check_bounds: invalid partnum %d", p); + if ((c < 0) || (c > ((nf >> 1) - 1))) + err(set_err(EINVAL), "check_bounds: out of bounds %d", c); } void @@ -443,7 +452,7 @@ writeGbe_part(int p) { swap(p); /* swap bytes on big-endian host CPUs */ if(pwrite(fd, (uint8_t *) gbe[p], nf, p * partsize) != nf) - err(SET_ERR(ECANCELED), + err(set_err(ECANCELED), "Can't write %ld b to '%s' p%d", nf, fname, p); } @@ -451,32 +460,16 @@ writeGbe_part(int p) void swap(int partnum) { - uint8_t *n = (uint8_t *) gbe[partnum]; + uint8_t *n = gbe[partnum]; for (size_t w = NVM_SIZE * ((uint8_t *) &e)[0], x = 1; w < NVM_SIZE; w += 2, x += 2) { + uint8_t chg = n[w]; n[w] ^= n[x]; - n[x] ^= n[w]; - n[w] ^= n[x]; + n[x] ^= chg; } } -#ifdef __OpenBSD__ -void -block_unveil(void) -{ - if (flags == O_RDONLY) { - err_if(unveil(fname, "r") == -1); - err_if(unveil(NULL, NULL) == -1); - err_if(pledge("stdio rpath", NULL) == -1); - } else { - err_if(unveil(fname, "rw") == -1); - err_if(unveil(NULL, NULL) == -1); - err_if(pledge("stdio rpath wpath", NULL) == -1); - } -} -#endif - void usage(char *util) { @@ -494,5 +487,5 @@ usage(char *util) " %s FILE brick 0|1\n" " %s FILE setchecksum 0|1\n", util, util, util, util, util, util, util); - err(SET_ERR(ECANCELED), "Too few arguments"); + err(set_err(ECANCELED), "Too few arguments"); } |
