diff options
| author | Luis R. Rodriguez <mcgrof@kernel.org> | 2017-07-12 17:33:33 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-12 19:26:00 -0400 |
| commit | d383d48470819e86fe30eb72f0e9494e1ee0e2af (patch) | |
| tree | 70be7478d13013b86d3d757577a5c60e89f95603 /kernel | |
| parent | a19ac3374995382a994653ff372b98ea7cbad548 (diff) | |
sysctl: fold sysctl_writes_strict checks into helper
The mode sysctl_writes_strict positional checks keep being copy and pasted
as we add new proc handlers. Just add a helper to avoid code duplication.
Link: http://lkml.kernel.org/r/20170519033554.18592-4-mcgrof@kernel.org
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
Suggested-by: Kees Cook <keescook@chromium.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sysctl.c | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 02725178694a..6f3bb1f099fa 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
| @@ -1971,6 +1971,32 @@ static void warn_sysctl_write(struct ctl_table *table) | |||
| 1971 | } | 1971 | } |
| 1972 | 1972 | ||
| 1973 | /** | 1973 | /** |
| 1974 | * proc_first_pos_non_zero_ignore - check if firs position is allowed | ||
| 1975 | * @ppos: file position | ||
| 1976 | * @table: the sysctl table | ||
| 1977 | * | ||
| 1978 | * Returns true if the first position is non-zero and the sysctl_writes_strict | ||
| 1979 | * mode indicates this is not allowed for numeric input types. String proc | ||
| 1980 | * hadlers can ignore the return value. | ||
| 1981 | */ | ||
| 1982 | static bool proc_first_pos_non_zero_ignore(loff_t *ppos, | ||
| 1983 | struct ctl_table *table) | ||
| 1984 | { | ||
| 1985 | if (!*ppos) | ||
| 1986 | return false; | ||
| 1987 | |||
| 1988 | switch (sysctl_writes_strict) { | ||
| 1989 | case SYSCTL_WRITES_STRICT: | ||
| 1990 | return true; | ||
| 1991 | case SYSCTL_WRITES_WARN: | ||
| 1992 | warn_sysctl_write(table); | ||
| 1993 | return false; | ||
| 1994 | default: | ||
| 1995 | return false; | ||
| 1996 | } | ||
| 1997 | } | ||
| 1998 | |||
| 1999 | /** | ||
| 1974 | * proc_dostring - read a string sysctl | 2000 | * proc_dostring - read a string sysctl |
| 1975 | * @table: the sysctl table | 2001 | * @table: the sysctl table |
| 1976 | * @write: %TRUE if this is a write to the sysctl file | 2002 | * @write: %TRUE if this is a write to the sysctl file |
| @@ -1990,8 +2016,8 @@ static void warn_sysctl_write(struct ctl_table *table) | |||
| 1990 | int proc_dostring(struct ctl_table *table, int write, | 2016 | int proc_dostring(struct ctl_table *table, int write, |
| 1991 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2017 | void __user *buffer, size_t *lenp, loff_t *ppos) |
| 1992 | { | 2018 | { |
| 1993 | if (write && *ppos && sysctl_writes_strict == SYSCTL_WRITES_WARN) | 2019 | if (write) |
| 1994 | warn_sysctl_write(table); | 2020 | proc_first_pos_non_zero_ignore(ppos, table); |
| 1995 | 2021 | ||
| 1996 | return _proc_do_string((char *)(table->data), table->maxlen, write, | 2022 | return _proc_do_string((char *)(table->data), table->maxlen, write, |
| 1997 | (char __user *)buffer, lenp, ppos); | 2023 | (char __user *)buffer, lenp, ppos); |
| @@ -2193,17 +2219,8 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, | |||
| 2193 | conv = do_proc_dointvec_conv; | 2219 | conv = do_proc_dointvec_conv; |
| 2194 | 2220 | ||
| 2195 | if (write) { | 2221 | if (write) { |
| 2196 | if (*ppos) { | 2222 | if (proc_first_pos_non_zero_ignore(ppos, table)) |
| 2197 | switch (sysctl_writes_strict) { | 2223 | goto out; |
| 2198 | case SYSCTL_WRITES_STRICT: | ||
| 2199 | goto out; | ||
| 2200 | case SYSCTL_WRITES_WARN: | ||
| 2201 | warn_sysctl_write(table); | ||
| 2202 | break; | ||
| 2203 | default: | ||
| 2204 | break; | ||
| 2205 | } | ||
| 2206 | } | ||
| 2207 | 2224 | ||
| 2208 | if (left > PAGE_SIZE - 1) | 2225 | if (left > PAGE_SIZE - 1) |
| 2209 | left = PAGE_SIZE - 1; | 2226 | left = PAGE_SIZE - 1; |
| @@ -2468,17 +2485,8 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int | |||
| 2468 | left = *lenp; | 2485 | left = *lenp; |
| 2469 | 2486 | ||
| 2470 | if (write) { | 2487 | if (write) { |
| 2471 | if (*ppos) { | 2488 | if (proc_first_pos_non_zero_ignore(ppos, table)) |
| 2472 | switch (sysctl_writes_strict) { | 2489 | goto out; |
| 2473 | case SYSCTL_WRITES_STRICT: | ||
| 2474 | goto out; | ||
| 2475 | case SYSCTL_WRITES_WARN: | ||
| 2476 | warn_sysctl_write(table); | ||
| 2477 | break; | ||
| 2478 | default: | ||
| 2479 | break; | ||
| 2480 | } | ||
| 2481 | } | ||
| 2482 | 2490 | ||
| 2483 | if (left > PAGE_SIZE - 1) | 2491 | if (left > PAGE_SIZE - 1) |
| 2484 | left = PAGE_SIZE - 1; | 2492 | left = PAGE_SIZE - 1; |
