aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-10-04 20:13:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-05 14:04:56 -0400
commit77dd3b0bd17a0849b2f98b915ce3fc9247db1013 (patch)
treea6ff9f120d790b5559e3f91cf9849e9f84ee1e65
parent125c4c706b680c7831f0966ff873c1ad0354ec25 (diff)
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>
-rw-r--r--lib/parser.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/lib/parser.c b/lib/parser.c
index c4341008483..52cfa69f73d 100644
--- a/lib/parser.c
+++ b/lib/parser.c
@@ -122,13 +122,14 @@ int match_token(char *s, const match_table_t table, substring_t args[])
122 * 122 *
123 * Description: Given a &substring_t and a base, attempts to parse the substring 123 * Description: Given a &substring_t and a base, attempts to parse the substring
124 * as a number in that base. On success, sets @result to the integer represented 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 */
127static int match_number(substring_t *s, int *result, int base) 127static int match_number(substring_t *s, int *result, int base)
128{ 128{
129 char *endp; 129 char *endp;
130 char *buf; 130 char *buf;
131 int ret; 131 int ret;
132 long val;
132 size_t len = s->to - s->from; 133 size_t len = s->to - s->from;
133 134
134 buf = kmalloc(len + 1, GFP_KERNEL); 135 buf = kmalloc(len + 1, GFP_KERNEL);
@@ -136,10 +137,15 @@ static int match_number(substring_t *s, int *result, int base)
136 return -ENOMEM; 137 return -ENOMEM;
137 memcpy(buf, s->from, len); 138 memcpy(buf, s->from, len);
138 buf[len] = '\0'; 139 buf[len] = '\0';
139 *result = simple_strtol(buf, &endp, base); 140
140 ret = 0; 141 ret = 0;
142 val = simple_strtol(buf, &endp, base);
141 if (endp == buf) 143 if (endp == buf)
142 ret = -EINVAL; 144 ret = -EINVAL;
145 else if (val < (long)INT_MIN || val > (long)INT_MAX)
146 ret = -ERANGE;
147 else
148 *result = (int) val;
143 kfree(buf); 149 kfree(buf);
144 return ret; 150 return ret;
145} 151}