Blame SOURCES/CVE-2022-4378.patch

fe6cb8
From 794229b5711a96a488d85dd719511a278b4a4956 Mon Sep 17 00:00:00 2001
fe6cb8
From: Ryan Sullivan <rysulliv@redhat.com>
fe6cb8
Date: Fri, 27 Jan 2023 11:25:43 -0500
fe6cb8
Subject: [KPATCH CVE-2022-4378] kpatch fixes for CVE-2022-4378
fe6cb8
fe6cb8
fe6cb8
Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-7/-/merge_requests/51
fe6cb8
Approved-by: Yannick Cote (@ycote1)
fe6cb8
Approved-by: Joe Lawrence (@joe.lawrence)
fe6cb8
Kernels:
fe6cb8
3.10.0-1160.76.1.el7
fe6cb8
3.10.0-1160.80.1.el7
fe6cb8
3.10.0-1160.81.1.el7
fe6cb8
3.10.0-1160.83.1.el7
fe6cb8
fe6cb8
Changes since last build:
fe6cb8
[x86_64]:
fe6cb8
sysctl.o: changed function: __do_proc_dointvec
fe6cb8
sysctl.o: changed function: __do_proc_douintvec
fe6cb8
sysctl.o: changed function: __do_proc_doulongvec_minmax
fe6cb8
sysctl.o: changed function: proc_dostring
fe6cb8
sysctl.o: changed function: proc_get_long.constprop.13
fe6cb8
fe6cb8
[ppc64le]:
fe6cb8
sysctl.o: changed function: __do_proc_doulongvec_minmax
fe6cb8
sysctl.o: changed function: proc_do_cad_pid
fe6cb8
sysctl.o: changed function: proc_dointvec
fe6cb8
sysctl.o: changed function: proc_dointvec_jiffies
fe6cb8
sysctl.o: changed function: proc_dointvec_minmax
fe6cb8
sysctl.o: changed function: proc_dointvec_minmax_coredump
fe6cb8
sysctl.o: changed function: proc_dointvec_minmax_sysadmin
fe6cb8
sysctl.o: changed function: proc_dointvec_ms_jiffies
fe6cb8
sysctl.o: changed function: proc_dointvec_userhz_jiffies
fe6cb8
sysctl.o: changed function: proc_dopipe_max_size
fe6cb8
sysctl.o: changed function: proc_dostring
fe6cb8
sysctl.o: changed function: proc_dostring_coredump
fe6cb8
sysctl.o: changed function: proc_douintvec
fe6cb8
sysctl.o: changed function: proc_douintvec_minmax
fe6cb8
sysctl.o: changed function: proc_doulongvec_minmax
fe6cb8
sysctl.o: changed function: proc_doulongvec_ms_jiffies_minmax
fe6cb8
sysctl.o: changed function: proc_get_long.constprop.13
fe6cb8
sysctl.o: changed function: sysrq_sysctl_handler
fe6cb8
sysctl.o: new function: __do_proc_dointvec
fe6cb8
fe6cb8
---------------------------
fe6cb8
fe6cb8
Modifications:
fe6cb8
added '__attribute__((optimize("-fno-optimize-sibling-calls")))' to
fe6cb8
proc_dointvec_jiffies(), proc_dointvec_ms_jiffies(), proc_doulongvec_ms_jiffies_minmax(),
fe6cb8
proc_doulongvec_minmax(), proc_dointvec_userhz_jiffies(), and proc_dointvec() definitions.
fe6cb8
fe6cb8
commit f4f6d6bf0cd6fc3d1b88341f784b2f7e8589ff61
fe6cb8
Author: Wander Lairson Costa <wander@redhat.com>
fe6cb8
Date:   Tue Dec 13 08:13:31 2022 -0300
fe6cb8
fe6cb8
    proc: avoid integer type confusion in get_proc_long
fe6cb8
fe6cb8
    Bugzilla: https://bugzilla.redhat.com/2152565
fe6cb8
    CVE: CVE-2022-4378
fe6cb8
fe6cb8
    commit e6cfaf34be9fcd1a8285a294e18986bfc41a409c
fe6cb8
    Author: Linus Torvalds <torvalds@linux-foundation.org>
fe6cb8
    Date:   Mon Dec 5 11:33:40 2022 -0800
fe6cb8
fe6cb8
        proc: avoid integer type confusion in get_proc_long
fe6cb8
fe6cb8
        proc_get_long() is passed a size_t, but then assigns it to an 'int'
fe6cb8
        variable for the length.  Let's not do that, even if our IO paths are
fe6cb8
        limited to MAX_RW_COUNT (exactly because of these kinds of type errors).
fe6cb8
fe6cb8
        So do the proper test in the rigth type.
fe6cb8
fe6cb8
        Reported-by: Kyle Zeng <zengyhkyle@gmail.com>
fe6cb8
        Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fe6cb8
fe6cb8
    Signed-off-by: Wander Lairson Costa <wander@redhat.com>
fe6cb8
fe6cb8
commit c727ac3f665ed51c096edeedf039552cea6053f6
fe6cb8
Author: Wander Lairson Costa <wander@redhat.com>
fe6cb8
Date:   Tue Dec 13 08:12:23 2022 -0300
fe6cb8
fe6cb8
    proc: proc_skip_spaces() shouldn't think it is working on C strings
fe6cb8
fe6cb8
    Bugzilla: https://bugzilla.redhat.com/2152565
fe6cb8
    CVE: CVE-2022-4378
fe6cb8
fe6cb8
    Conflicts: some context hunks because we are way behind upstream.
fe6cb8
fe6cb8
    commit bce9332220bd677d83b19d21502776ad555a0e73
fe6cb8
    Author: Linus Torvalds <torvalds@linux-foundation.org>
fe6cb8
    Date:   Mon Dec 5 12:09:06 2022 -0800
fe6cb8
fe6cb8
        proc: proc_skip_spaces() shouldn't think it is working on C strings
fe6cb8
fe6cb8
        proc_skip_spaces() seems to think it is working on C strings, and ends
fe6cb8
        up being just a wrapper around skip_spaces() with a really odd calling
fe6cb8
        convention.
fe6cb8
fe6cb8
        Instead of basing it on skip_spaces(), it should have looked more like
fe6cb8
        proc_skip_char(), which really is the exact same function (except it
fe6cb8
        skips a particular character, rather than whitespace).  So use that as
fe6cb8
        inspiration, odd coding and all.
fe6cb8
fe6cb8
        Now the calling convention actually makes sense and works for the
fe6cb8
        intended purpose.
fe6cb8
fe6cb8
        Reported-and-tested-by: Kyle Zeng <zengyhkyle@gmail.com>
fe6cb8
        Acked-by: Eric Dumazet <edumazet@google.com>
fe6cb8
        Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fe6cb8
fe6cb8
    Signed-off-by: Wander Lairson Costa <wander@redhat.com>
fe6cb8
fe6cb8
Signed-off-by: Ryan Sullivan <rysulliv@redhat.com>
fe6cb8
---
fe6cb8
 kernel/sysctl.c | 36 +++++++++++++++++++++---------------
fe6cb8
 1 file changed, 21 insertions(+), 15 deletions(-)
fe6cb8
fe6cb8
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
fe6cb8
index 62e2788cf09a..6f7d80afda89 100644
fe6cb8
--- a/kernel/sysctl.c
fe6cb8
+++ b/kernel/sysctl.c
fe6cb8
@@ -1999,13 +1999,14 @@ int proc_dostring(struct ctl_table *table, int write,
fe6cb8
 			       (char __user *)buffer, lenp, ppos);
fe6cb8
 }
fe6cb8
 
fe6cb8
-static size_t proc_skip_spaces(char **buf)
fe6cb8
+static void proc_skip_spaces(char **buf, size_t *size)
fe6cb8
 {
fe6cb8
-	size_t ret;
fe6cb8
-	char *tmp = skip_spaces(*buf);
fe6cb8
-	ret = tmp - *buf;
fe6cb8
-	*buf = tmp;
fe6cb8
-	return ret;
fe6cb8
+	while (*size) {
fe6cb8
+		if (!isspace(**buf))
fe6cb8
+			break;
fe6cb8
+		(*size)--;
fe6cb8
+		(*buf)++;
fe6cb8
+	}
fe6cb8
 }
fe6cb8
 
fe6cb8
 static void proc_skip_char(char **buf, size_t *size, const char v)
fe6cb8
@@ -2074,13 +2075,12 @@ static int proc_get_long(char **buf, size_t *size,
fe6cb8
 			  unsigned long *val, bool *neg,
fe6cb8
 			  const char *perm_tr, unsigned perm_tr_len, char *tr)
fe6cb8
 {
fe6cb8
-	int len;
fe6cb8
 	char *p, tmp[TMPBUFLEN];
fe6cb8
+	ssize_t len = *size;
fe6cb8
 
fe6cb8
-	if (!*size)
fe6cb8
+	if (len <= 0)
fe6cb8
 		return -EINVAL;
fe6cb8
 
fe6cb8
-	len = *size;
fe6cb8
 	if (len > TMPBUFLEN - 1)
fe6cb8
 		len = TMPBUFLEN - 1;
fe6cb8
 
fe6cb8
@@ -2250,7 +2250,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
fe6cb8
 		bool neg;
fe6cb8
 
fe6cb8
 		if (write) {
fe6cb8
-			left -= proc_skip_spaces(&kbuf);
fe6cb8
+			proc_skip_spaces(&kbuf, &left);
fe6cb8
 
fe6cb8
 			if (!left)
fe6cb8
 				break;
fe6cb8
@@ -2281,7 +2281,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
fe6cb8
 	if (!write && !first && left && !err)
fe6cb8
 		err = proc_put_char(&buffer, &left, '\n');
fe6cb8
 	if (write && !err && left)
fe6cb8
-		left -= proc_skip_spaces(&kbuf);
fe6cb8
+		proc_skip_spaces(&kbuf, &left);
fe6cb8
 free:
fe6cb8
 	if (write) {
fe6cb8
 		free_page(page);
fe6cb8
@@ -2331,7 +2331,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data,
fe6cb8
 	if (IS_ERR(kbuf))
fe6cb8
 		return -EINVAL;
fe6cb8
 
fe6cb8
-	left -= proc_skip_spaces(&p);
fe6cb8
+	proc_skip_spaces(&p, &left);
fe6cb8
 	if (!left) {
fe6cb8
 		err = -EINVAL;
fe6cb8
 		goto out_free;
fe6cb8
@@ -2351,7 +2351,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data,
fe6cb8
 	}
fe6cb8
 
fe6cb8
 	if (!err && left)
fe6cb8
-		left -= proc_skip_spaces(&p);
fe6cb8
+		proc_skip_spaces(&p, &left);
fe6cb8
 
fe6cb8
 out_free:
fe6cb8
 	kfree(kbuf);
fe6cb8
@@ -2457,6 +2457,7 @@ static int do_proc_douintvec(struct ctl_table *table, int write,
fe6cb8
  *
fe6cb8
  * Returns 0 on success.
fe6cb8
  */
fe6cb8
+__attribute__((optimize("-fno-optimize-sibling-calls")))
fe6cb8
 int proc_dointvec(struct ctl_table *table, int write,
fe6cb8
 		     void __user *buffer, size_t *lenp, loff_t *ppos)
fe6cb8
 {
fe6cb8
@@ -2775,7 +2776,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
fe6cb8
 		if (write) {
fe6cb8
 			bool neg;
fe6cb8
 
fe6cb8
-			left -= proc_skip_spaces(&kbuf);
fe6cb8
+			proc_skip_spaces(&kbuf, &left);
fe6cb8
 
fe6cb8
 			err = proc_get_long(&kbuf, &left, &val, &neg,
fe6cb8
 					     proc_wspace_sep,
fe6cb8
@@ -2800,7 +2801,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
fe6cb8
 	if (!write && !first && left && !err)
fe6cb8
 		err = proc_put_char(&buffer, &left, '\n');
fe6cb8
 	if (write && !err)
fe6cb8
-		left -= proc_skip_spaces(&kbuf);
fe6cb8
+		proc_skip_spaces(&kbuf, &left);
fe6cb8
 free:
fe6cb8
 	if (write) {
fe6cb8
 		free_page(page);
fe6cb8
@@ -2839,6 +2840,7 @@ static int do_proc_doulongvec_minmax(struct ctl_table *table, int write,
fe6cb8
  *
fe6cb8
  * Returns 0 on success.
fe6cb8
  */
fe6cb8
+__attribute__((optimize("-fno-optimize-sibling-calls")))
fe6cb8
 int proc_doulongvec_minmax(struct ctl_table *table, int write,
fe6cb8
 			   void __user *buffer, size_t *lenp, loff_t *ppos)
fe6cb8
 {
fe6cb8
@@ -2862,6 +2864,7 @@ int proc_doulongvec_minmax(struct ctl_table *table, int write,
fe6cb8
  *
fe6cb8
  * Returns 0 on success.
fe6cb8
  */
fe6cb8
+__attribute__((optimize("-fno-optimize-sibling-calls")))
fe6cb8
 int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
fe6cb8
 				      void __user *buffer,
fe6cb8
 				      size_t *lenp, loff_t *ppos)
fe6cb8
@@ -2957,6 +2960,7 @@ static int do_proc_dointvec_ms_jiffies_conv(bool *negp, unsigned long *lvalp,
fe6cb8
  *
fe6cb8
  * Returns 0 on success.
fe6cb8
  */
fe6cb8
+__attribute__((optimize("-fno-optimize-sibling-calls")))
fe6cb8
 int proc_dointvec_jiffies(struct ctl_table *table, int write,
fe6cb8
 			  void __user *buffer, size_t *lenp, loff_t *ppos)
fe6cb8
 {
fe6cb8
@@ -2979,6 +2983,7 @@ int proc_dointvec_jiffies(struct ctl_table *table, int write,
fe6cb8
  *
fe6cb8
  * Returns 0 on success.
fe6cb8
  */
fe6cb8
+__attribute__((optimize("-fno-optimize-sibling-calls")))
fe6cb8
 int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write,
fe6cb8
 				 void __user *buffer, size_t *lenp, loff_t *ppos)
fe6cb8
 {
fe6cb8
@@ -3002,6 +3007,7 @@ int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write,
fe6cb8
  *
fe6cb8
  * Returns 0 on success.
fe6cb8
  */
fe6cb8
+__attribute__((optimize("-fno-optimize-sibling-calls")))
fe6cb8
 int proc_dointvec_ms_jiffies(struct ctl_table *table, int write,
fe6cb8
 			     void __user *buffer, size_t *lenp, loff_t *ppos)
fe6cb8
 {
fe6cb8
-- 
fe6cb8
2.39.1
fe6cb8
fe6cb8