[PATCH v3 2/7] parse-options: check for overflow when parsing integers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We use `strtol()` to parse the argument of `OPTION_INTEGER` options. And
while we do check that the argument was fully parsed, we don't check
`errno` at all and thus may not notice cases where `strtol()` fails.
Most importantly, this includes the case where the parsed integer does
not fit into a `long` at all. The consequence is that we'll happily
continue with an invalid value.

Fix the bug by checking `errno`. Note that this change alone is not
sufficient to detect all possible overflows: `strtol()` returns a
`long`, but we end up assigning the value to an `int` and will thus
truncate the value. This will be fixed in subsequent patches.

Signed-off-by: Patrick Steinhardt <ps@xxxxxx>
---
 parse-options.c          | 10 +++++++++-
 t/t0040-parse-options.sh |  6 ++++++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/parse-options.c b/parse-options.c
index 35fbb3b0d63..e8c08e55e02 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -185,12 +185,20 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
 		if (!*arg)
 			return error(_("%s expects a numerical value"),
 				     optname(opt, flags));
+
+		errno = 0;
 		*(int *)opt->value = strtol(arg, (char **)&s, 10);
 		if (*s)
 			return error(_("%s expects a numerical value"),
 				     optname(opt, flags));
-		return 0;
+		if (errno == ERANGE)
+			return error(_("value %s for %s not in range [%"PRIdMAX",%"PRIdMAX"]"),
+				     arg, optname(opt, flags), (intmax_t)LONG_MIN, (intmax_t)LONG_MAX);
+		if (errno)
+			return error_errno(_("value %s for %s cannot be parsed"),
+					   arg, optname(opt, flags));
 
+		return 0;
 	case OPTION_MAGNITUDE:
 		if (unset) {
 			*(unsigned long *)opt->value = 0;
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index 2fe3522305f..5eb1feb61b4 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -783,4 +783,10 @@ test_expect_success 'magnitude with units but no numbers' '
 	test_must_be_empty out
 '
 
+test_expect_success 'overflowing integer' '
+	test_must_fail test-tool parse-options --integer 9223372036854775808 >out 2>err &&
+	test_grep "value .* for option .* not in range" err &&
+	test_must_be_empty out
+'
+
 test_done

-- 
2.49.0.805.g082f7c87e0.dirty





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux