提交 71afffbe 编写于 作者: L Linus Torvalds 提交者: Zheng Zengkai

proc: proc_skip_spaces() shouldn't think it is working on C strings

stable inclusion
from stable-v5.10.157
commit 9ba389863ac63032d4b6ffad2c90a62cd78082ee
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I65TQE
CVE: CVE-2022-4378

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9ba389863ac63032d4b6ffad2c90a62cd78082ee

--------------------------------

commit bce93322 upstream.

proc_skip_spaces() seems to think it is working on C strings, and ends
up being just a wrapper around skip_spaces() with a really odd calling
convention.

Instead of basing it on skip_spaces(), it should have looked more like
proc_skip_char(), which really is the exact same function (except it
skips a particular character, rather than whitespace).  So use that as
inspiration, odd coding and all.

Now the calling convention actually makes sense and works for the
intended purpose.
Reported-and-tested-by: NKyle Zeng <zengyhkyle@gmail.com>
Acked-by: NEric Dumazet <edumazet@google.com>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NLong Li <leo.lilong@huawei.com>
Reviewed-by: NZhang Yi <yi.zhang@huawei.com>
Reviewed-by: NXiu Jianfeng <xiujianfeng@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 b0b5b1f9
...@@ -397,13 +397,14 @@ int proc_dostring(struct ctl_table *table, int write, ...@@ -397,13 +397,14 @@ int proc_dostring(struct ctl_table *table, int write,
ppos); ppos);
} }
static size_t proc_skip_spaces(char **buf) static void proc_skip_spaces(char **buf, size_t *size)
{ {
size_t ret; while (*size) {
char *tmp = skip_spaces(*buf); if (!isspace(**buf))
ret = tmp - *buf; break;
*buf = tmp; (*size)--;
return ret; (*buf)++;
}
} }
static void proc_skip_char(char **buf, size_t *size, const char v) static void proc_skip_char(char **buf, size_t *size, const char v)
...@@ -635,7 +636,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, ...@@ -635,7 +636,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
bool neg; bool neg;
if (write) { if (write) {
left -= proc_skip_spaces(&p); proc_skip_spaces(&p, &left);
if (!left) if (!left)
break; break;
...@@ -662,7 +663,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, ...@@ -662,7 +663,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
if (!write && !first && left && !err) if (!write && !first && left && !err)
proc_put_char(&buffer, &left, '\n'); proc_put_char(&buffer, &left, '\n');
if (write && !err && left) if (write && !err && left)
left -= proc_skip_spaces(&p); proc_skip_spaces(&p, &left);
if (write && first) if (write && first)
return err ? : -EINVAL; return err ? : -EINVAL;
*lenp -= left; *lenp -= left;
...@@ -704,7 +705,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data, ...@@ -704,7 +705,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data,
if (left > PAGE_SIZE - 1) if (left > PAGE_SIZE - 1)
left = PAGE_SIZE - 1; left = PAGE_SIZE - 1;
left -= proc_skip_spaces(&p); proc_skip_spaces(&p, &left);
if (!left) { if (!left) {
err = -EINVAL; err = -EINVAL;
goto out_free; goto out_free;
...@@ -724,7 +725,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data, ...@@ -724,7 +725,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data,
} }
if (!err && left) if (!err && left)
left -= proc_skip_spaces(&p); proc_skip_spaces(&p, &left);
out_free: out_free:
if (err) if (err)
...@@ -1182,7 +1183,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, ...@@ -1182,7 +1183,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table,
if (write) { if (write) {
bool neg; bool neg;
left -= proc_skip_spaces(&p); proc_skip_spaces(&p, &left);
if (!left) if (!left)
break; break;
...@@ -1211,7 +1212,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, ...@@ -1211,7 +1212,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table,
if (!write && !first && left && !err) if (!write && !first && left && !err)
proc_put_char(&buffer, &left, '\n'); proc_put_char(&buffer, &left, '\n');
if (write && !err) if (write && !err)
left -= proc_skip_spaces(&p); proc_skip_spaces(&p, &left);
if (write && first) if (write && first)
return err ? : -EINVAL; return err ? : -EINVAL;
*lenp -= left; *lenp -= left;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册