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

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>

authored by

Luis R. Rodriguez and committed by
Linus Torvalds
d383d484 a19ac337

+32 -24
+32 -24
kernel/sysctl.c
··· 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 2000 * proc_dostring - read a string sysctl 1975 2001 * @table: the sysctl table 1976 2002 * @write: %TRUE if this is a write to the sysctl file ··· 2016 1990 int proc_dostring(struct ctl_table *table, int write, 2017 1991 void __user *buffer, size_t *lenp, loff_t *ppos) 2018 1992 { 2019 - if (write && *ppos && sysctl_writes_strict == SYSCTL_WRITES_WARN) 2020 - warn_sysctl_write(table); 1993 + if (write) 1994 + proc_first_pos_non_zero_ignore(ppos, table); 2021 1995 2022 1996 return _proc_do_string((char *)(table->data), table->maxlen, write, 2023 1997 (char __user *)buffer, lenp, ppos); ··· 2219 2193 conv = do_proc_dointvec_conv; 2220 2194 2221 2195 if (write) { 2222 - if (*ppos) { 2223 - switch (sysctl_writes_strict) { 2224 - case SYSCTL_WRITES_STRICT: 2225 - goto out; 2226 - case SYSCTL_WRITES_WARN: 2227 - warn_sysctl_write(table); 2228 - break; 2229 - default: 2230 - break; 2231 - } 2232 - } 2196 + if (proc_first_pos_non_zero_ignore(ppos, table)) 2197 + goto out; 2233 2198 2234 2199 if (left > PAGE_SIZE - 1) 2235 2200 left = PAGE_SIZE - 1; ··· 2485 2468 left = *lenp; 2486 2469 2487 2470 if (write) { 2488 - if (*ppos) { 2489 - switch (sysctl_writes_strict) { 2490 - case SYSCTL_WRITES_STRICT: 2491 - goto out; 2492 - case SYSCTL_WRITES_WARN: 2493 - warn_sysctl_write(table); 2494 - break; 2495 - default: 2496 - break; 2497 - } 2498 - } 2471 + if (proc_first_pos_non_zero_ignore(ppos, table)) 2472 + goto out; 2499 2473 2500 2474 if (left > PAGE_SIZE - 1) 2501 2475 left = PAGE_SIZE - 1;