summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2026-03-06 23:07:29 +0000
committerLeah Rowe <leah@libreboot.org>2026-03-06 23:07:29 +0000
commit69c4d70650e8c3236444181f33cadc2f53d85bb8 (patch)
treebbbedf51267d3615f6e376da71d4ed12100881b1 /util
parent9b6f2a2f7ec8873536226b333de492356c1c2663 (diff)
util/nvmutil: safer argv part number parsing
we now handle signedness properly, which is implementation defined, on char integers where signed/unsigned is not specified. Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'util')
-rw-r--r--util/nvmutil/nvmutil.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c
index f64c6468..b0fc23f3 100644
--- a/util/nvmutil/nvmutil.c
+++ b/util/nvmutil/nvmutil.c
@@ -30,6 +30,7 @@
static void reset_global_state(void);
static void set_cmd(int argc, char *argv[]);
static void check_cmd_args(int argc, char *argv[]);
+static size_t conv_argv_part_num(const char *part_str);
static void set_io_flags(int argc, char *argv[]);
static void open_gbe_file(void);
#ifndef HAVE_ARC4RANDOM
@@ -297,16 +298,43 @@ check_cmd_args(int argc, char *argv[])
if (argc > 3)
mac_str = argv[3];
} else if (cmd != NULL && argc > 3) { /* user-supplied partnum */
- part = argv[3][0] - '0';
- if (argv[3][1] != '\0')
- err(EINVAL, "Invalid part string: %s", argv[3]);
- check_part_num(part);
+ part = conv_argv_part_num(argv[3]);
}
if (cmd == NULL)
err(EINVAL, "Bad command");
}
+/*
+ * Not to be confused with check_part_num()
+ */
+static size_t
+conv_argv_part_num(const char *part_str)
+{
+ size_t rval;
+ unsigned char ch;
+
+ /*
+ * Because char signedness is implementation is
+ * implementation-defined, we must assumed that
+ * it is signed, and guard accordingly.
+ *
+ * Do not use check_part_num() here. The same check
+ * is done *here*, but on a character, with the
+ * above caveat in mind.
+ */
+
+ if (strlen(part_str) != 1)
+ err(EINVAL, "Partnum string '%s' wrong length.",
+ part_str);
+
+ ch = (unsigned char)part_str[0];
+ ch -= '0';
+
+ check_part_num(rval = (size_t)ch);
+ return (size_t)ch;
+}
+
static void
set_io_flags(int argc, char *argv[])
{
@@ -888,11 +916,14 @@ set_part_modified(size_t p)
part_modified[p] = 1;
}
+/*
+ * Not to be confused with conv_argv_part_num()
+ */
static void
check_part_num(size_t p)
{
if (p > 1)
- err(ECANCELED, "Bad part number %zu", p);
+ err(EINVAL, "Bad part number (%zu)", p);
}
static void