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): Commit7c60c48f58
("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:7c60c48f58
("sysctl: Improve the sysctl sanity checks") Link: http://lkml.kernel.org/r/20170519033554.18592-2-mcgrof@kernel.org Signed-off-by: Luis 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: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
a711bdc095
commit
89c5b53b16
|
@ -1066,7 +1066,7 @@ static int sysctl_check_table(const char *path, struct ctl_table *table)
|
|||
int err = 0;
|
||||
for (; table->procname; table++) {
|
||||
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) ||
|
||||
(table->proc_handler == proc_dointvec) ||
|
||||
|
@ -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_ms_jiffies_minmax)) {
|
||||
if (!table->data)
|
||||
err = sysctl_err(path, table, "No data");
|
||||
err |= sysctl_err(path, table, "No data");
|
||||
if (!table->maxlen)
|
||||
err = sysctl_err(path, table, "No maxlen");
|
||||
err |= sysctl_err(path, table, "No maxlen");
|
||||
}
|
||||
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)
|
||||
err = sysctl_err(path, table, "bogus .mode 0%o",
|
||||
err |= sysctl_err(path, table, "bogus .mode 0%o",
|
||||
table->mode);
|
||||
}
|
||||
return err;
|
||||
|
|
Loading…
Reference in New Issue