diff options
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r-- | kernel/sysctl.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 14f30b4a1b64..1877ebe85c95 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -67,6 +67,8 @@ | |||
67 | #include <linux/bpf.h> | 67 | #include <linux/bpf.h> |
68 | #include <linux/mount.h> | 68 | #include <linux/mount.h> |
69 | 69 | ||
70 | #include "../lib/kstrtox.h" | ||
71 | |||
70 | #include <linux/uaccess.h> | 72 | #include <linux/uaccess.h> |
71 | #include <asm/processor.h> | 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 | #define TMPBUFLEN 22 | 2157 | #define TMPBUFLEN 22 |
2121 | /** | 2158 | /** |
2122 | * proc_get_long - reads an ASCII formatted integer from a user buffer | 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 | if (!isdigit(*p)) | 2197 | if (!isdigit(*p)) |
2161 | return -EINVAL; | 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 | len = p - tmp; | 2203 | len = p - tmp; |
2166 | 2204 | ||