Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lib/parser.c: avoid overflow in match_number()

The result of converting an integer value to another signed integer type
that's unable to represent the original value is implementation defined.
(See notes in section 6.3.1.3 of the C standard.)

In match_number(), the result of simple_strtol() (which returns type long)
is assigned to a value of type int.

Instead, handle the result of simple_strtol() in a well-defined way, and
return -ERANGE if the result won't fit in the int variable used to hold
the parsed result.

No current callers pay attention to the particular error value returned,
so this additional return code shouldn't do any harm.

[akpm@linux-foundation.org: coding-style tweaks]
Signed-off-by: Alex Elder <elder@inktank.com>
Cc: Randy Dunlap <rdunlap@xenotime.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Alex Elder and committed by
Linus Torvalds
77dd3b0b 125c4c70

+8 -2
+8 -2
lib/parser.c
··· 122 122 * 123 123 * Description: Given a &substring_t and a base, attempts to parse the substring 124 124 * as a number in that base. On success, sets @result to the integer represented 125 - * by the string and returns 0. Returns either -ENOMEM or -EINVAL on failure. 125 + * by the string and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. 126 126 */ 127 127 static int match_number(substring_t *s, int *result, int base) 128 128 { 129 129 char *endp; 130 130 char *buf; 131 131 int ret; 132 + long val; 132 133 size_t len = s->to - s->from; 133 134 134 135 buf = kmalloc(len + 1, GFP_KERNEL); ··· 137 136 return -ENOMEM; 138 137 memcpy(buf, s->from, len); 139 138 buf[len] = '\0'; 140 - *result = simple_strtol(buf, &endp, base); 139 + 141 140 ret = 0; 141 + val = simple_strtol(buf, &endp, base); 142 142 if (endp == buf) 143 143 ret = -EINVAL; 144 + else if (val < (long)INT_MIN || val > (long)INT_MAX) 145 + ret = -ERANGE; 146 + else 147 + *result = (int) val; 144 148 kfree(buf); 145 149 return ret; 146 150 }