[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20170519033554.18592-4-mcgrof@kernel.org>
Date: Thu, 18 May 2017 20:35:52 -0700
From: "Luis R. Rodriguez" <mcgrof@...nel.org>
To: viro@...iv.linux.org.uk, akpm@...ux-foundation.org,
ebiederm@...ssion.com, keescook@...omium.org, acme@...hat.com,
mingo@...nel.org, mgorman@...e.de, subashab@...eaurora.org
Cc: jeyu@...hat.com, rusty@...tcorp.com.au, swhiteho@...hat.com,
deepa.kernel@...il.com, matt@...eblueprint.co.uk,
adobriyan@...il.com, bp@...e.de, zlpnobody@...il.com,
dmitry.torokhov@...il.com, shuah@...nel.org,
torvalds@...ux-foundation.org, linux@...ck-us.net,
linux-kernel@...r.kernel.org,
"Luis R. Rodriguez" <mcgrof@...nel.org>
Subject: [PATCH v3 3/5] 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.
Suggested-by: Kees Cook <keescook@...omium.org>
Signed-off-by: Luis R. Rodriguez <mcgrof@...nel.org>
---
kernel/sysctl.c | 56 ++++++++++++++++++++++++++++++++------------------------
1 file changed, 32 insertions(+), 24 deletions(-)
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 02725178694a..6f3bb1f099fa 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1971,6 +1971,32 @@ static void warn_sysctl_write(struct ctl_table *table)
}
/**
+ * 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
* @write: %TRUE if this is a write to the sysctl file
@@ -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;
--
2.11.0
Powered by blists - more mailing lists