[patch] expand_number(3): check strtoumax(3) for ERANGE

Sergey Kandaurov pluknet at gmail.com
Fri Jul 26 08:17:14 UTC 2013


Hi,

As of now expand_number(3) does not properly check too large data.
It currently handles errors only for prefixed values.

(an argument is intentionally signed to be closer to the real buggish world,
e.g. as it's currently done in truncate(1). This should not compile, though
see bsd.sys.mk at 169723).

	int64_t sz;

	if (expand_number(argv[1], &sz) < 0)
		err(1, "expand_number");

	printf("%ld\n", sz);


[pluknet at omg] ./expand_number 8000p
9007199254740992000
[pluknet at omg] ./expand_number 9000p
-8313644912125935616
[pluknet at omg] ./expand_number 19000p
expand_number: expand_number: Result too large

[pluknet at omg] ./expand_number 0x7fffffffffffffff (INT64_MAX)
9223372036854775807
[pluknet at omg] ./expand_number 0xffffffffffffffff (UINT64_MAX)
-1

But

[pluknet at omg] ./expand_number 0xfffffffffffffffff (> UINT64_MAX)
-1 (actually UINTMAX_MAX expressed as signed)

This is how it should work:

[pluknet at omg] ./expand_number 0xfffffffffffffffff (> UINT64_MAX)
expand_number: expand_number: Result too large

Index: lib/libutil/expand_number.c
===================================================================
--- lib/libutil/expand_number.c	(revision 253546)
+++ lib/libutil/expand_number.c	(working copy)
@@ -55,6 +55,10 @@

 	number = strtoumax(buf, &endptr, 0);

+	if (number == UINTMAX_MAX && errno == ERANGE) {
+		return (-1);
+	}
+
 	if (endptr == buf) {
 		/* No valid digits. */
 		errno = EINVAL;

-- 
wbr,
pluknet


More information about the freebsd-current mailing list