Commit 626cdf5c authored by Long Li's avatar Long Li Committed by Zheng Zengkai
Browse files

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: default avatarKyle Zeng <zengyhkyle@gmail.com>
Acked-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarLong Li <leo.lilong@huawei.com>
Reviewed-by: default avatarZhang Yi <yi.zhang@huawei.com>
Reviewed-by: default avatarXiu Jianfeng <xiujianfeng@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 87e56df7
Loading
Loading
Loading
Loading
+13 −12
Original line number Diff line number Diff line
@@ -396,13 +396,14 @@ int proc_dostring(struct ctl_table *table, int write,
			ppos);
}

static size_t proc_skip_spaces(char **buf)
static void proc_skip_spaces(char **buf, size_t *size)
{
	size_t ret;
	char *tmp = skip_spaces(*buf);
	ret = tmp - *buf;
	*buf = tmp;
	return ret;
	while (*size) {
		if (!isspace(**buf))
			break;
		(*size)--;
		(*buf)++;
	}
}

static void proc_skip_char(char **buf, size_t *size, const char v)
@@ -634,7 +635,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
		bool neg;

		if (write) {
			left -= proc_skip_spaces(&p);
			proc_skip_spaces(&p, &left);

			if (!left)
				break;
@@ -661,7 +662,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
	if (!write && !first && left && !err)
		proc_put_char(&buffer, &left, '\n');
	if (write && !err && left)
		left -= proc_skip_spaces(&p);
		proc_skip_spaces(&p, &left);
	if (write && first)
		return err ? : -EINVAL;
	*lenp -= left;
@@ -703,7 +704,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data,
	if (left > PAGE_SIZE - 1)
		left = PAGE_SIZE - 1;

	left -= proc_skip_spaces(&p);
	proc_skip_spaces(&p, &left);
	if (!left) {
		err = -EINVAL;
		goto out_free;
@@ -723,7 +724,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data,
	}

	if (!err && left)
		left -= proc_skip_spaces(&p);
		proc_skip_spaces(&p, &left);

out_free:
	if (err)
@@ -1181,7 +1182,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table,
		if (write) {
			bool neg;

			left -= proc_skip_spaces(&p);
			proc_skip_spaces(&p, &left);
			if (!left)
				break;

@@ -1210,7 +1211,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table,
	if (!write && !first && left && !err)
		proc_put_char(&buffer, &left, '\n');
	if (write && !err)
		left -= proc_skip_spaces(&p);
		proc_skip_spaces(&p, &left);
	if (write && first)
		return err ? : -EINVAL;
	*lenp -= left;