Blame SOURCES/CVE-2022-4378.patch

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