From: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
To: linux-kernel@vger.kernel.org
Cc: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>,
Heinrich Schuchardt <xypron.glpk@gmx.de>,
Andrew Morton <akpm@linux-foundation.org>,
Kees Cook <keescook@chromium.org>,
"David S. Miller" <davem@davemloft.net>,
Ingo Molnar <mingo@redhat.com>
Subject: [PATCH] sysctl: Handle error writing UINT_MAX to u32 fields
Date: Wed, 17 Aug 2016 18:23:26 -0600 [thread overview]
Message-ID: <1471479806-5252-1-git-send-email-subashab@codeaurora.org> (raw)
We have scripts which write to certain fields on 3.18 kernels but
this seems to be failing on 4.4 kernels. An entry which we write
to here is xfrm_aevent_rseqth which is u32.
echo 4294967295 > /proc/sys/net/core/xfrm_aevent_rseqth
Commit 230633d109e3 ("kernel/sysctl.c: detect overflows when
converting to int") prevented writing to sysctl entries when
integer overflow occurs. However, this does not apply to unsigned
integers.
Heinrich suggested that we introduce a new option to handle 64 bit
limits and set min as 0 and max as UINT_MAX. This might not work
as it leads to issues similar to __do_proc_doulongvec_minmax.
Alternatively, we would need to change the datatype of the entry
to 64 bit.
static int __do_proc_doulongvec_minmax(void *data, struct ctl_table
{
i = (unsigned long *) data; //This cast is causing to
read beyond the size of data (u32)
vleft = table->maxlen / sizeof(unsigned long); //vleft is 0
because maxlen is sizeof(u32) which is lesser than sizeof(unsigned
long) on x86_64.
Introduce a new proc handler proc_douintvec. Individual proc
entries will need to be updated to use the new handler.
Fixes: 230633d109e3 ("kernel/sysctl.c:detect overflows when converting to int")
Cc: Heinrich Schuchardt <xypron.glpk@gmx.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Ingo Molnar <mingo@redhat.com>
Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
---
include/linux/sysctl.h | 2 ++
kernel/sysctl.c | 42 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+)
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 697e160..a4f7203 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -42,6 +42,8 @@ extern int proc_dostring(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
extern int proc_dointvec(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
+extern int proc_douintvec(struct ctl_table *, int,
+ void __user *, size_t *, loff_t *);
extern int proc_dointvec_minmax(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
extern int proc_dointvec_jiffies(struct ctl_table *, int,
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index b43d0b2..96437af 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -2140,6 +2140,21 @@ static int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp,
return 0;
}
+static int do_proc_douintvec_conv(bool *negp, unsigned long *lvalp,
+ int *valp,
+ int write, void *data)
+{
+ if (write) {
+ if (*negp)
+ return -EINVAL;
+ *valp = *lvalp;
+ } else {
+ unsigned int val = *valp;
+ *lvalp = (unsigned long)val;
+ }
+ return 0;
+}
+
static const char proc_wspace_sep[] = { ' ', '\t', '\n' };
static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
@@ -2263,6 +2278,26 @@ int proc_dointvec(struct ctl_table *table, int write,
NULL,NULL);
}
+/**
+ * proc_douintvec - read a vector of unsigned integers
+ * @table: the sysctl table
+ * @write: %TRUE if this is a write to the sysctl file
+ * @buffer: the user buffer
+ * @lenp: the size of the user buffer
+ * @ppos: file position
+ *
+ * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer
+ * values from/to the user buffer, treated as an ASCII string.
+ *
+ * Returns 0 on success.
+ */
+int proc_douintvec(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ return do_proc_dointvec(table,write,buffer,lenp,ppos,
+ do_proc_douintvec_conv, NULL);
+}
+
/*
* Taint values can only be increased
* This means we can safely use a temporary.
@@ -2858,6 +2893,12 @@ int proc_dointvec(struct ctl_table *table, int write,
return -ENOSYS;
}
+int proc_douintvec(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ return -ENOSYS;
+}
+
int proc_dointvec_minmax(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
@@ -2903,6 +2944,7 @@ int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
* exception granted :-)
*/
EXPORT_SYMBOL(proc_dointvec);
+EXPORT_SYMBOL(proc_douintvec);
EXPORT_SYMBOL(proc_dointvec_jiffies);
EXPORT_SYMBOL(proc_dointvec_minmax);
EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
--
1.9.1
next reply other threads:[~2016-08-18 0:24 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-18 0:23 Subash Abhinov Kasiviswanathan [this message]
-- strict thread matches above, loose matches on Subject: below --
2016-06-18 1:12 [PATCH] sysctl: Handle error writing UINT_MAX to u32 fields Subash Abhinov Kasiviswanathan
2016-06-18 2:07 ` kbuild test robot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1471479806-5252-1-git-send-email-subashab@codeaurora.org \
--to=subashab@codeaurora.org \
--cc=akpm@linux-foundation.org \
--cc=davem@davemloft.net \
--cc=keescook@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=xypron.glpk@gmx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.