summaryrefslogtreecommitdiff
path: root/util/nvmutil/lib/command.c
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2026-03-20 04:02:51 +0000
committerLeah Rowe <leah@libreboot.org>2026-03-22 13:50:44 +0000
commit6838db4647b600bf5b356429f54850bf801e7ba4 (patch)
treecc98541897703d2949af27dc050cad8cba5061a0 /util/nvmutil/lib/command.c
parentf50ffd6bb13c04cb185fb6311f8875582bf18388 (diff)
WIP: hardened mktemp
i'm pretty much nearly there. still no dir support, only files. i won't keep amending now - will do more, then squash later. Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'util/nvmutil/lib/command.c')
-rw-r--r--util/nvmutil/lib/command.c171
1 files changed, 94 insertions, 77 deletions
diff --git a/util/nvmutil/lib/command.c b/util/nvmutil/lib/command.c
index 95e1b4f7..3a863d23 100644
--- a/util/nvmutil/lib/command.c
+++ b/util/nvmutil/lib/command.c
@@ -21,10 +21,10 @@
void
sanitize_command_list(void)
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
- unsigned long c;
- unsigned long num_commands;
+ size_t c;
+ size_t num_commands;
num_commands = items(x->cmd);
@@ -33,37 +33,41 @@ sanitize_command_list(void)
}
void
-sanitize_command_index(unsigned long c)
+sanitize_command_index(size_t c)
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
struct commands *cmd = &x->cmd[c];
int _flag;
- unsigned long gbe_rw_size;
+ size_t gbe_rw_size;
+
+ size_t rval;
check_command_num(c);
if (cmd->argc < 3)
err(EINVAL, "cmd index %lu: argc below 3, %d",
- (unsigned long)c, cmd->argc);
+ (size_t)c, cmd->argc);
if (cmd->str == NULL)
err(EINVAL, "cmd index %lu: NULL str",
- (unsigned long)c);
+ (size_t)c);
if (*cmd->str == '\0')
err(EINVAL, "cmd index %lu: empty str",
- (unsigned long)c);
+ (size_t)c);
+
+ if (slen(cmd->str, MAX_CMD_LEN +1, &rval) < 0)
+ err(errno, "Could not get command length");
- if (xstrxlen(cmd->str, MAX_CMD_LEN + 1) >
- MAX_CMD_LEN) {
+ if (rval > MAX_CMD_LEN) {
err(EINVAL, "cmd index %lu: str too long: %s",
- (unsigned long)c, cmd->str);
+ (size_t)c, cmd->str);
}
if (cmd->run == NULL)
err(EINVAL, "cmd index %lu: cmd ptr null",
- (unsigned long)c);
+ (size_t)c);
check_bin(cmd->arg_part, "cmd.arg_part");
check_bin(cmd->chksum_read, "cmd.chksum_read");
@@ -77,12 +81,12 @@ sanitize_command_index(unsigned long c)
break;
default:
err(EINVAL, "Unsupported rw_size: %lu",
- (unsigned long)gbe_rw_size);
+ (size_t)gbe_rw_size);
}
if (gbe_rw_size > GBE_PART_SIZE)
err(EINVAL, "rw_size larger than GbE part: %lu",
- (unsigned long)gbe_rw_size);
+ (size_t)gbe_rw_size);
_flag = (cmd->flags & O_ACCMODE);
@@ -94,18 +98,22 @@ sanitize_command_index(unsigned long c)
void
set_cmd(int argc, char *argv[])
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
const char *cmd;
- unsigned long c;
+ int rval;
+
+ size_t c;
for (c = 0; c < items(x->cmd); c++) {
cmd = x->cmd[c].str;
- /* not the right command */
- if (xstrxcmp(argv[2], cmd, MAX_CMD_LEN) != 0)
- continue;
+ if (scmp(argv[2], cmd, MAX_CMD_LEN, &rval) < 0)
+ err_no_cleanup(EINVAL,
+ "could not compare command strings");
+ if (rval != 0)
+ continue; /* not the right command */
/* valid command found */
if (argc >= x->cmd[c].argc) {
@@ -115,7 +123,7 @@ set_cmd(int argc, char *argv[])
return;
}
- err(EINVAL,
+ err_no_cleanup(EINVAL,
"Too few args on command '%s'", cmd);
}
@@ -125,8 +133,8 @@ set_cmd(int argc, char *argv[])
void
set_cmd_args(int argc, char *argv[])
{
- struct xstate *x = xstatus(0, NULL);
- unsigned long i = x->i;
+ struct xstate *x = xstatus();
+ size_t i = x->i;
struct commands *cmd = &x->cmd[i];
struct xfile *f = &x->f;
@@ -159,7 +167,7 @@ set_cmd_args(int argc, char *argv[])
}
}
-unsigned long
+size_t
conv_argv_part_num(const char *part_str)
{
unsigned char ch;
@@ -173,21 +181,21 @@ conv_argv_part_num(const char *part_str)
if (ch < '0' || ch > '1')
err(EINVAL, "Bad part number (%c)", ch);
- return (unsigned long)(ch - '0');
+ return (size_t)(ch - '0');
}
void
-check_command_num(unsigned long c)
+check_command_num(size_t c)
{
if (!valid_command(c))
err(EINVAL, "Invalid run_cmd arg: %lu",
- (unsigned long)c);
+ (size_t)c);
}
unsigned char
-valid_command(unsigned long c)
+valid_command(size_t c)
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
struct commands *cmd;
if (c >= items(x->cmd))
@@ -206,10 +214,10 @@ valid_command(unsigned long c)
void
cmd_helper_setmac(void)
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
struct macaddr *mac = &x->mac;
- unsigned long partnum;
+ size_t partnum;
check_cmd(cmd_helper_setmac, "setmac");
@@ -223,12 +231,17 @@ cmd_helper_setmac(void)
void
parse_mac_string(void)
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
struct macaddr *mac = &x->mac;
- unsigned long mac_byte;
+ size_t mac_byte;
- if (xstrxlen(x->mac.str, 18) != 17)
+ size_t rval;
+
+ if (slen(x->mac.str, 18, &rval) < 0)
+ err(EINVAL, "Could not determine MAC length");
+
+ if (rval != 17)
err(EINVAL, "MAC address is the wrong length");
memset(mac->mac_buf, 0, sizeof(mac->mac_buf));
@@ -244,15 +257,15 @@ parse_mac_string(void)
}
void
-set_mac_byte(unsigned long mac_byte_pos)
+set_mac_byte(size_t mac_byte_pos)
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
struct macaddr *mac = &x->mac;
char separator;
- unsigned long mac_str_pos;
- unsigned long mac_nib_pos;
+ size_t mac_str_pos;
+ size_t mac_nib_pos;
mac_str_pos = mac_byte_pos * 3;
@@ -267,10 +280,10 @@ 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)
+set_mac_nib(size_t mac_str_pos,
+ size_t mac_byte_pos, size_t mac_nib_pos)
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
struct macaddr *mac = &x->mac;
char mac_ch;
@@ -278,9 +291,13 @@ set_mac_nib(unsigned long mac_str_pos,
mac_ch = mac->str[mac_str_pos + mac_nib_pos];
- if ((hex_num = hextonum(mac_ch)) > 15)
- err(EINVAL, "Invalid character '%c'",
- mac->str[mac_str_pos + mac_nib_pos]);
+ if ((hex_num = hextonum(mac_ch)) > 15) {
+ if (hex_num >= 17)
+ err(EIO, "Randomisation failure");
+ else
+ err(EINVAL, "Invalid character '%c'",
+ mac->str[mac_str_pos + mac_nib_pos]);
+ }
/* If random, ensure that local/unicast bits are set.
*/
@@ -298,13 +315,13 @@ set_mac_nib(unsigned long mac_str_pos,
}
void
-write_mac_part(unsigned long partnum)
+write_mac_part(size_t partnum)
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
struct xfile *f = &x->f;
struct macaddr *mac = &x->mac;
- unsigned long w;
+ size_t w;
check_bin(partnum, "part number");
if (!f->part_valid[partnum])
@@ -314,17 +331,17 @@ write_mac_part(unsigned long partnum)
set_nvm_word(w, partnum, mac->mac_buf[w]);
printf("Wrote MAC address to part %lu: ",
- (unsigned long)partnum);
+ (size_t)partnum);
print_mac_from_nvm(partnum);
}
void
cmd_helper_dump(void)
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
struct xfile *f = &x->f;
- unsigned long p;
+ size_t p;
check_cmd(cmd_helper_dump, "dump");
@@ -338,12 +355,12 @@ cmd_helper_dump(void)
fprintf(stderr,
"BAD checksum %04x in part %lu (expected %04x)\n",
nvm_word(NVM_CHECKSUM_WORD, p),
- (unsigned long)p,
+ (size_t)p,
calculated_checksum(p));
}
printf("MAC (part %lu): ",
- (unsigned long)p);
+ (size_t)p);
print_mac_from_nvm(p);
@@ -352,9 +369,9 @@ cmd_helper_dump(void)
}
void
-print_mac_from_nvm(unsigned long partnum)
+print_mac_from_nvm(size_t partnum)
{
- unsigned long c;
+ size_t c;
unsigned short val16;
for (c = 0; c < 3; c++) {
@@ -373,16 +390,16 @@ print_mac_from_nvm(unsigned long partnum)
}
void
-hexdump(unsigned long partnum)
+hexdump(size_t partnum)
{
- unsigned long c;
- unsigned long row;
+ size_t c;
+ size_t row;
unsigned short val16;
for (row = 0; row < 8; row++) {
printf("%08lx ",
- (unsigned long)((unsigned long)row << 4));
+ (size_t)((size_t)row << 4));
for (c = 0; c < 8; c++) {
@@ -404,24 +421,24 @@ hexdump(unsigned long partnum)
void
cmd_helper_swap(void)
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
struct xfile *f = &x->f;
check_cmd(cmd_helper_swap, "swap");
memcpy(
- f->buf + (unsigned long)GBE_WORK_SIZE,
+ f->buf + (size_t)GBE_WORK_SIZE,
f->buf,
GBE_PART_SIZE);
memcpy(
f->buf,
- f->buf + (unsigned long)GBE_PART_SIZE,
+ f->buf + (size_t)GBE_PART_SIZE,
GBE_PART_SIZE);
memcpy(
- f->buf + (unsigned long)GBE_PART_SIZE,
- f->buf + (unsigned long)GBE_WORK_SIZE,
+ f->buf + (size_t)GBE_PART_SIZE,
+ f->buf + (size_t)GBE_WORK_SIZE,
GBE_PART_SIZE);
set_part_modified(0);
@@ -431,14 +448,14 @@ cmd_helper_swap(void)
void
cmd_helper_copy(void)
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
struct xfile *f = &x->f;
check_cmd(cmd_helper_copy, "copy");
memcpy(
- f->buf + (unsigned long)((f->part ^ 1) * GBE_PART_SIZE),
- f->buf + (unsigned long)(f->part * GBE_PART_SIZE),
+ f->buf + (size_t)((f->part ^ 1) * GBE_PART_SIZE),
+ f->buf + (size_t)(f->part * GBE_PART_SIZE),
GBE_PART_SIZE);
set_part_modified(f->part ^ 1);
@@ -447,7 +464,7 @@ cmd_helper_copy(void)
void
cmd_helper_cat(void)
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
check_cmd(cmd_helper_cat, "cat");
@@ -458,7 +475,7 @@ cmd_helper_cat(void)
void
cmd_helper_cat16(void)
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
check_cmd(cmd_helper_cat16, "cat16");
@@ -469,7 +486,7 @@ cmd_helper_cat16(void)
void
cmd_helper_cat128(void)
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
check_cmd(cmd_helper_cat128, "cat128");
@@ -478,18 +495,18 @@ cmd_helper_cat128(void)
}
void
-cat(unsigned long nff)
+cat(size_t nff)
{
- struct xstate *x = xstatus(0, NULL);
+ struct xstate *x = xstatus();
struct xfile *f = &x->f;
- unsigned long p;
- unsigned long ff;
+ size_t p;
+ size_t ff;
p = 0;
ff = 0;
- if ((unsigned long)x->cat != nff) {
+ if ((size_t)x->cat != nff) {
err(ECANCELED, "erroneous call to cat");
}
@@ -501,7 +518,7 @@ cat(unsigned long nff)
for (p = 0; p < 2; p++) {
cat_buf(f->bufcmp +
- (unsigned long)(p * (f->gbe_file_size >> 1)));
+ (size_t)(p * (f->gbe_file_size >> 1)));
for (ff = 0; ff < nff; ff++) {
@@ -525,8 +542,8 @@ void
check_cmd(void (*fn)(void),
const char *name)
{
- struct xstate *x = xstatus(0, NULL);
- unsigned long i = x->i;
+ struct xstate *x = xstatus();
+ size_t i = x->i;
if (x->cmd[i].run != fn)
err(ECANCELED, "Running %s, but cmd %s is set",