From 5b91e65d83213b25cc9529884a2106eee80c6c04 Mon Sep 17 00:00:00 2001
From: Ryan Sullivan <rysulliv@redhat.com>
Date: Thu, 26 Jan 2023 09:44:30 -0500
Subject: [KPATCH CVE-2022-4378] kpatch fixes for CVE-2022-4378
Kernels:
5.14.0-162.6.1.el9_1
5.14.0-162.12.1.el9_1
Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-9/-/merge_requests/19
Approved-by: Joe Lawrence (@joe.lawrence)
Approved-by: Yannick Cote (@ycote1)
Changes since last build:
arches: x86_64 ppc64le
l2cap_core.o: changed function: l2cap_rx_state_recv
l2cap_core.o: changed function: l2cap_stream_rx
nfs4proc.o: changed function: nfsd4_copy
nfs4proc.o: changed function: nfsd4_do_async_copy
nft_payload.o: changed function: nft_payload_copy_vlan
sysctl.o: changed function: __do_proc_dointvec
sysctl.o: changed function: __do_proc_douintvec
sysctl.o: changed function: __do_proc_doulongvec_minmax
sysctl.o: changed function: proc_get_long.constprop.0
---------------------------
Modifications: none
commit d4c4d465e31fae6c3729b9c52a6bc3610494ead4
Author: Wander Lairson Costa <wander@redhat.com>
Date: Mon Dec 12 15:30:46 2022 -0300
proc: avoid integer type confusion in get_proc_long
Bugzilla: https://bugzilla.redhat.com/2152580
CVE: CVE-2022-4378
Y-Commit: ab93541c2e72e570f9b6cf79ff943400961a30e1
O-Bugzilla: https://bugzilla.redhat.com/2152581
O-CVE: CVE-2022-4378
commit e6cfaf34be9fcd1a8285a294e18986bfc41a409c
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date: Mon Dec 5 11:33:40 2022 -0800
proc: avoid integer type confusion in get_proc_long
proc_get_long() is passed a size_t, but then assigns it to an 'int'
variable for the length. Let's not do that, even if our IO paths are
limited to MAX_RW_COUNT (exactly because of these kinds of type errors).
So do the proper test in the rigth type.
Reported-by: Kyle Zeng <zengyhkyle@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Signed-off-by: Patrick Talbert <ptalbert@redhat.com>
commit 250391dd6ddc268d65901a1eaeb966a7256ef1cb
Author: Wander Lairson Costa <wander@redhat.com>
Date: Mon Dec 12 15:30:50 2022 -0300
proc: proc_skip_spaces() shouldn't think it is working on C strings
Bugzilla: https://bugzilla.redhat.com/2152580
CVE: CVE-2022-4378
Y-Commit: a664fa0ecf20645f630e278b6da6aaabb3192954
O-Bugzilla: https://bugzilla.redhat.com/2152581
O-CVE: CVE-2022-4378
commit bce9332220bd677d83b19d21502776ad555a0e73
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date: Mon Dec 5 12:09:06 2022 -0800
proc: proc_skip_spaces() shouldn't think it is working on C strings
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: Kyle Zeng <zengyhkyle@gmail.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Signed-off-by: Patrick Talbert <ptalbert@redhat.com>
Signed-off-by: Ryan Sullivan <rysulliv@redhat.com>
---
kernel/sysctl.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 0dd902ee206e..e72cf05ca07b 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -391,13 +391,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)
@@ -466,13 +467,12 @@ static int proc_get_long(char **buf, size_t *size,
unsigned long *val, bool *neg,
const char *perm_tr, unsigned perm_tr_len, char *tr)
{
- int len;
char *p, tmp[TMPBUFLEN];
+ ssize_t len = *size;
- if (!*size)
+ if (len <= 0)
return -EINVAL;
- len = *size;
if (len > TMPBUFLEN - 1)
len = TMPBUFLEN - 1;
@@ -645,7 +645,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;
@@ -672,7 +672,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;
@@ -714,7 +714,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;
@@ -734,7 +734,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)
@@ -1271,7 +1271,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;
@@ -1299,7 +1299,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;
--
2.39.1