From: Zhiqiang Liu <liuzhiqiang26@huawei.com>
To: <mcgrof@kernel.org>, <keescook@chromium.org>,
<linux-kernel@vger.kernel.org>, <linux-fsdevel@vger.kernel.org>
Cc: <mingfangsen@huawei.com>, <wangxiaogang3@huawei.com>,
"Zhoukang (A)" <zhoukang7@huawei.com>
Subject: [PATCH next] sysctl: add proc_dointvec_jiffies_minmax to limit the min/max write value
Date: Wed, 17 Apr 2019 19:12:58 +0800 [thread overview]
Message-ID: <032e024f-2b1b-a980-1b53-d903bc8db297@huawei.com> (raw)
From: Zhiqiang Liu <liuzhiqiang26@huawei.com>
In proc_dointvec_jiffies func, the write value is only checked
whether it is larger than INT_MAX. If the write value is less
than zero, it can also be successfully writen in the data.
However, in some scenarios, users would adopt the data to
set timers or check whether time is expired. Generally, the data
will be cast to an unsigned type variable, then the negative data
becomes a very large unsigned value, which leads to long waits
or other unpredictable problems.
Here, we add a new func, proc_dointvec_jiffies_minmax, to limit the
min/max write value, which is similar to the proc_dointvec_minmax func.
Signed-off-by: Zhiqiang Liu <liuzhiqiang26@huawei.com>
Reported-by: Qiang Ning <ningqiang1@huawei.com>
Reviewed-by: Jie Liu <liujie165@huawei.com>
---
include/linux/sysctl.h | 2 ++
kernel/sysctl.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index b769ecf..8bde8a0 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -53,6 +53,8 @@ extern int proc_douintvec_minmax(struct ctl_table *table, int write,
loff_t *ppos);
extern int proc_dointvec_jiffies(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
+extern int proc_dointvec_jiffies_minmax(struct ctl_table *, int,
+ void __user *, size_t *, loff_t *);
extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
extern int proc_dointvec_ms_jiffies(struct ctl_table *, int,
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c9ec050..8e1eb59 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -2967,10 +2967,15 @@ static int do_proc_dointvec_jiffies_conv(bool *negp, unsigned long *lvalp,
int *valp,
int write, void *data)
{
+ struct do_proc_dointvec_minmax_conv_param *param = data;
+
if (write) {
if (*lvalp > INT_MAX / HZ)
return 1;
*valp = *negp ? -(*lvalp*HZ) : (*lvalp*HZ);
+ if ((param->min && (*param->min)*HZ > *valp) ||
+ (param->max && (*param->max)*HZ < *valp))
+ return -EINVAL;
} else {
int val = *valp;
unsigned long lval;
@@ -3053,7 +3058,37 @@ int proc_dointvec_jiffies(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_dointvec_jiffies_conv,NULL);
+ do_proc_dointvec_jiffies_conv, NULL);
+}
+
+/**
+ * proc_dointvec_jiffies_minmax - read a vector of integers as seconds with min/max values
+ * @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) integer
+ * values from/to the user buffer, treated as an ASCII string.
+ * The values read are assumed to be in seconds, and are converted into
+ * jiffies.
+ *
+ * This routine will ensure the values are within the range specified by
+ * table->extra1 (min) and table->extra2 (max).
+ *
+ * Returns 0 on success or -EINVAL on write when the range check fails.
+ */
+int proc_dointvec_jiffies_minmax(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ struct do_proc_dointvec_minmax_conv_param param = {
+ .min = (int *) table->extra1,
+ .max = (int *) table->extra2,
+ };
+
+ return do_proc_dointvec(table, write, buffer, lenp, ppos,
+ do_proc_dointvec_jiffies_conv, ¶m);
}
/**
@@ -3301,6 +3336,12 @@ int proc_dointvec_jiffies(struct ctl_table *table, int write,
return -ENOSYS;
}
+int proc_dointvec_jiffies_minmax(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ return -ENOSYS;
+}
+
int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
@@ -3359,6 +3400,7 @@ static int proc_dointvec_minmax_bpf_stats(struct ctl_table *table, int write,
EXPORT_SYMBOL(proc_dointvec);
EXPORT_SYMBOL(proc_douintvec);
EXPORT_SYMBOL(proc_dointvec_jiffies);
+EXPORT_SYMBOL(proc_dointvec_jiffies_minmax);
EXPORT_SYMBOL(proc_dointvec_minmax);
EXPORT_SYMBOL_GPL(proc_douintvec_minmax);
EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
--
1.8.3.1
next reply other threads:[~2019-04-17 11:13 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-17 11:12 Zhiqiang Liu [this message]
2019-04-24 4:04 ` [PATCH next] sysctl: add proc_dointvec_jiffies_minmax to limit the min/max write value Zhiqiang Liu
2019-05-15 14:53 ` Zhiqiang Liu
2019-05-15 17:06 ` Kees Cook
2019-06-04 15:27 ` Zhiqiang Liu
2019-07-01 8:06 ` Zhiqiang Liu
2019-07-02 19:32 ` Luis Chamberlain
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=032e024f-2b1b-a980-1b53-d903bc8db297@huawei.com \
--to=liuzhiqiang26@huawei.com \
--cc=keescook@chromium.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mcgrof@kernel.org \
--cc=mingfangsen@huawei.com \
--cc=wangxiaogang3@huawei.com \
--cc=zhoukang7@huawei.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).