|
67 | 67 | #include <linux/bpf.h>
|
68 | 68 | #include <linux/mount.h>
|
69 | 69 |
|
| 70 | +#include "../lib/kstrtox.h" |
| 71 | + |
70 | 72 | #include <linux/uaccess.h>
|
71 | 73 | #include <asm/processor.h>
|
72 | 74 |
|
@@ -2117,6 +2119,41 @@ static void proc_skip_char(char **buf, size_t *size, const char v)
|
2117 | 2119 | }
|
2118 | 2120 | }
|
2119 | 2121 |
|
| 2122 | +/** |
| 2123 | + * strtoul_lenient - parse an ASCII formatted integer from a buffer and only |
| 2124 | + * fail on overflow |
| 2125 | + * |
| 2126 | + * @cp: kernel buffer containing the string to parse |
| 2127 | + * @endp: pointer to store the trailing characters |
| 2128 | + * @base: the base to use |
| 2129 | + * @res: where the parsed integer will be stored |
| 2130 | + * |
| 2131 | + * In case of success 0 is returned and @res will contain the parsed integer, |
| 2132 | + * @endp will hold any trailing characters. |
| 2133 | + * This function will fail the parse on overflow. If there wasn't an overflow |
| 2134 | + * the function will defer the decision what characters count as invalid to the |
| 2135 | + * caller. |
| 2136 | + */ |
| 2137 | +static int strtoul_lenient(const char *cp, char **endp, unsigned int base, |
| 2138 | + unsigned long *res) |
| 2139 | +{ |
| 2140 | + unsigned long long result; |
| 2141 | + unsigned int rv; |
| 2142 | + |
| 2143 | + cp = _parse_integer_fixup_radix(cp, &base); |
| 2144 | + rv = _parse_integer(cp, base, &result); |
| 2145 | + if ((rv & KSTRTOX_OVERFLOW) || (result != (unsigned long)result)) |
| 2146 | + return -ERANGE; |
| 2147 | + |
| 2148 | + cp += rv; |
| 2149 | + |
| 2150 | + if (endp) |
| 2151 | + *endp = (char *)cp; |
| 2152 | + |
| 2153 | + *res = (unsigned long)result; |
| 2154 | + return 0; |
| 2155 | +} |
| 2156 | + |
2120 | 2157 | #define TMPBUFLEN 22
|
2121 | 2158 | /**
|
2122 | 2159 | * proc_get_long - reads an ASCII formatted integer from a user buffer
|
@@ -2160,7 +2197,8 @@ static int proc_get_long(char **buf, size_t *size,
|
2160 | 2197 | if (!isdigit(*p))
|
2161 | 2198 | return -EINVAL;
|
2162 | 2199 |
|
2163 |
| - *val = simple_strtoul(p, &p, 0); |
| 2200 | + if (strtoul_lenient(p, &p, 0, val)) |
| 2201 | + return -EINVAL; |
2164 | 2202 |
|
2165 | 2203 | len = p - tmp;
|
2166 | 2204 |
|
|
0 commit comments