Commit d383d484 authored by Luis R. Rodriguez's avatar Luis R. Rodriguez Committed by Linus Torvalds

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.orgSigned-off-by: default avatarLuis R. Rodriguez <mcgrof@kernel.org>
Suggested-by: default avatarKees 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a19ac337
...@@ -1970,6 +1970,32 @@ static void warn_sysctl_write(struct ctl_table *table) ...@@ -1970,6 +1970,32 @@ static void warn_sysctl_write(struct ctl_table *table)
current->comm, table->procname); 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 * proc_dostring - read a string sysctl
* @table: the sysctl table * @table: the sysctl table
...@@ -1990,8 +2016,8 @@ static void warn_sysctl_write(struct ctl_table *table) ...@@ -1990,8 +2016,8 @@ static void warn_sysctl_write(struct ctl_table *table)
int proc_dostring(struct ctl_table *table, int write, int proc_dostring(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void __user *buffer, size_t *lenp, loff_t *ppos)
{ {
if (write && *ppos && sysctl_writes_strict == SYSCTL_WRITES_WARN) if (write)
warn_sysctl_write(table); proc_first_pos_non_zero_ignore(ppos, table);
return _proc_do_string((char *)(table->data), table->maxlen, write, return _proc_do_string((char *)(table->data), table->maxlen, write,
(char __user *)buffer, lenp, ppos); (char __user *)buffer, lenp, ppos);
...@@ -2193,17 +2219,8 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, ...@@ -2193,17 +2219,8 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
conv = do_proc_dointvec_conv; conv = do_proc_dointvec_conv;
if (write) { if (write) {
if (*ppos) { if (proc_first_pos_non_zero_ignore(ppos, table))
switch (sysctl_writes_strict) {
case SYSCTL_WRITES_STRICT:
goto out; goto out;
case SYSCTL_WRITES_WARN:
warn_sysctl_write(table);
break;
default:
break;
}
}
if (left > PAGE_SIZE - 1) if (left > PAGE_SIZE - 1)
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 ...@@ -2468,17 +2485,8 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
left = *lenp; left = *lenp;
if (write) { if (write) {
if (*ppos) { if (proc_first_pos_non_zero_ignore(ppos, table))
switch (sysctl_writes_strict) {
case SYSCTL_WRITES_STRICT:
goto out; goto out;
case SYSCTL_WRITES_WARN:
warn_sysctl_write(table);
break;
default:
break;
}
}
if (left > PAGE_SIZE - 1) if (left > PAGE_SIZE - 1)
left = PAGE_SIZE - 1; left = PAGE_SIZE - 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment