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>
This commit is contained in:
Родитель
a19ac33749
Коммит
d383d48470
|
@ -1970,6 +1970,32 @@ static void warn_sysctl_write(struct ctl_table *table)
|
|||
current->comm, table->procname);
|
||||
}
|
||||
|
||||
/**
|
||||
* proc_first_pos_non_zero_ignore - check if firs position is allowed
|
||||
* @ppos: file position
|
||||
* @table: the sysctl table
|
||||
*
|
||||
* Returns true if the first position is non-zero and the sysctl_writes_strict
|
||||
* mode indicates this is not allowed for numeric input types. String proc
|
||||
* hadlers can ignore the return value.
|
||||
*/
|
||||
static bool proc_first_pos_non_zero_ignore(loff_t *ppos,
|
||||
struct ctl_table *table)
|
||||
{
|
||||
if (!*ppos)
|
||||
return false;
|
||||
|
||||
switch (sysctl_writes_strict) {
|
||||
case SYSCTL_WRITES_STRICT:
|
||||
return true;
|
||||
case SYSCTL_WRITES_WARN:
|
||||
warn_sysctl_write(table);
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* proc_dostring - read a string sysctl
|
||||
* @table: the sysctl table
|
||||
|
@ -1990,8 +2016,8 @@ static void warn_sysctl_write(struct ctl_table *table)
|
|||
int proc_dostring(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
if (write && *ppos && sysctl_writes_strict == SYSCTL_WRITES_WARN)
|
||||
warn_sysctl_write(table);
|
||||
if (write)
|
||||
proc_first_pos_non_zero_ignore(ppos, table);
|
||||
|
||||
return _proc_do_string((char *)(table->data), table->maxlen, write,
|
||||
(char __user *)buffer, lenp, ppos);
|
||||
|
@ -2193,17 +2219,8 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
|
|||
conv = do_proc_dointvec_conv;
|
||||
|
||||
if (write) {
|
||||
if (*ppos) {
|
||||
switch (sysctl_writes_strict) {
|
||||
case SYSCTL_WRITES_STRICT:
|
||||
goto out;
|
||||
case SYSCTL_WRITES_WARN:
|
||||
warn_sysctl_write(table);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (proc_first_pos_non_zero_ignore(ppos, table))
|
||||
goto out;
|
||||
|
||||
if (left > PAGE_SIZE - 1)
|
||||
left = PAGE_SIZE - 1;
|
||||
|
@ -2468,17 +2485,8 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
|
|||
left = *lenp;
|
||||
|
||||
if (write) {
|
||||
if (*ppos) {
|
||||
switch (sysctl_writes_strict) {
|
||||
case SYSCTL_WRITES_STRICT:
|
||||
goto out;
|
||||
case SYSCTL_WRITES_WARN:
|
||||
warn_sysctl_write(table);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (proc_first_pos_non_zero_ignore(ppos, table))
|
||||
goto out;
|
||||
|
||||
if (left > PAGE_SIZE - 1)
|
||||
left = PAGE_SIZE - 1;
|
||||
|
|
Загрузка…
Ссылка в новой задаче