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

sysctl: fix lax sysctl_check_table() sanity check

Patch series "sysctl: few fixes", v5.

I've been working on making kmod more deterministic, and as I did that I
couldn't help but notice a few issues with sysctl.  My end goal was just
to fix unsigned int support, which back then was completely broken.
Liping Zhang has sent up small atomic fixes, however it still missed yet
one more fix and Alexey Dobriyan had also suggested to just drop array
support given its complexity.

I have inspected array support using Coccinelle and indeed its not that
popular, so if in fact we can avoid it for new interfaces, I agree its
best.

I did develop a sysctl stress driver but will hold that off for another
series.

This patch (of 5):

Commit 7c60c48f ("sysctl: Improve the sysctl sanity checks")
improved sanity checks considerbly, however the enhancements on
sysctl_check_table() meant adding a functional change so that only the
last table entry's sanity error is propagated.  It also changed the way
errors were propagated so that each new check reset the err value, this
means only last sanity check computed is used for an error.  This has
been in the kernel since v3.4 days.

Fix this by carrying on errors from previous checks and iterations as we
traverse the table and ensuring we keep any error from previous checks.
We keep iterating on the table even if an error is found so we can
complain for all errors found in one shot.  This works as -EINVAL is
always returned on error anyway, and the check for error is any non-zero
value.

Fixes: 7c60c48f ("sysctl: Improve the sysctl sanity checks")
Link: http://lkml.kernel.org/r/20170519033554.18592-2-mcgrof@kernel.orgSigned-off-by: default avatarLuis R. Rodriguez <mcgrof@kernel.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Kees Cook <keescook@chromium.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a711bdc0
...@@ -1066,7 +1066,7 @@ static int sysctl_check_table(const char *path, struct ctl_table *table) ...@@ -1066,7 +1066,7 @@ static int sysctl_check_table(const char *path, struct ctl_table *table)
int err = 0; int err = 0;
for (; table->procname; table++) { for (; table->procname; table++) {
if (table->child) if (table->child)
err = sysctl_err(path, table, "Not a file"); err |= sysctl_err(path, table, "Not a file");
if ((table->proc_handler == proc_dostring) || if ((table->proc_handler == proc_dostring) ||
(table->proc_handler == proc_dointvec) || (table->proc_handler == proc_dointvec) ||
...@@ -1078,15 +1078,15 @@ static int sysctl_check_table(const char *path, struct ctl_table *table) ...@@ -1078,15 +1078,15 @@ static int sysctl_check_table(const char *path, struct ctl_table *table)
(table->proc_handler == proc_doulongvec_minmax) || (table->proc_handler == proc_doulongvec_minmax) ||
(table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) { (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) {
if (!table->data) if (!table->data)
err = sysctl_err(path, table, "No data"); err |= sysctl_err(path, table, "No data");
if (!table->maxlen) if (!table->maxlen)
err = sysctl_err(path, table, "No maxlen"); err |= sysctl_err(path, table, "No maxlen");
} }
if (!table->proc_handler) if (!table->proc_handler)
err = sysctl_err(path, table, "No proc_handler"); err |= sysctl_err(path, table, "No proc_handler");
if ((table->mode & (S_IRUGO|S_IWUGO)) != table->mode) if ((table->mode & (S_IRUGO|S_IWUGO)) != table->mode)
err = sysctl_err(path, table, "bogus .mode 0%o", err |= sysctl_err(path, table, "bogus .mode 0%o",
table->mode); table->mode);
} }
return err; return err;
......
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