]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 5 Feb 2021 09:02:29 +0000 (10:02 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 5 Feb 2021 09:02:29 +0000 (10:02 +0100)
added patches:
net_sched-gen_estimator-support-large-ewma-log.patch
sysctl-handle-overflow-in-proc_get_long.patch

queue-4.19/net_sched-gen_estimator-support-large-ewma-log.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/sysctl-handle-overflow-in-proc_get_long.patch [new file with mode: 0644]

diff --git a/queue-4.19/net_sched-gen_estimator-support-large-ewma-log.patch b/queue-4.19/net_sched-gen_estimator-support-large-ewma-log.patch
new file mode 100644 (file)
index 0000000..ed0b075
--- /dev/null
@@ -0,0 +1,90 @@
+From foo@baz Fri Feb  5 09:57:03 AM CET 2021
+From: Eric Dumazet <edumazet@google.com>
+Date: Thu, 14 Jan 2021 10:19:29 -0800
+Subject: net_sched: gen_estimator: support large ewma log
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit dd5e073381f2ada3630f36be42833c6e9c78b75e upstream
+
+syzbot report reminded us that very big ewma_log were supported in the past,
+even if they made litle sense.
+
+tc qdisc replace dev xxx root est 1sec 131072sec ...
+
+While fixing the bug, also add boundary checks for ewma_log, in line
+with range supported by iproute2.
+
+UBSAN: shift-out-of-bounds in net/core/gen_estimator.c:83:38
+shift exponent -1 is negative
+CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.10.0-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Call Trace:
+ <IRQ>
+ __dump_stack lib/dump_stack.c:79 [inline]
+ dump_stack+0x107/0x163 lib/dump_stack.c:120
+ ubsan_epilogue+0xb/0x5a lib/ubsan.c:148
+ __ubsan_handle_shift_out_of_bounds.cold+0xb1/0x181 lib/ubsan.c:395
+ est_timer.cold+0xbb/0x12d net/core/gen_estimator.c:83
+ call_timer_fn+0x1a5/0x710 kernel/time/timer.c:1417
+ expire_timers kernel/time/timer.c:1462 [inline]
+ __run_timers.part.0+0x692/0xa80 kernel/time/timer.c:1731
+ __run_timers kernel/time/timer.c:1712 [inline]
+ run_timer_softirq+0xb3/0x1d0 kernel/time/timer.c:1744
+ __do_softirq+0x2bc/0xa77 kernel/softirq.c:343
+ asm_call_irq_on_stack+0xf/0x20
+ </IRQ>
+ __run_on_irqstack arch/x86/include/asm/irq_stack.h:26 [inline]
+ run_on_irqstack_cond arch/x86/include/asm/irq_stack.h:77 [inline]
+ do_softirq_own_stack+0xaa/0xd0 arch/x86/kernel/irq_64.c:77
+ invoke_softirq kernel/softirq.c:226 [inline]
+ __irq_exit_rcu+0x17f/0x200 kernel/softirq.c:420
+ irq_exit_rcu+0x5/0x20 kernel/softirq.c:432
+ sysvec_apic_timer_interrupt+0x4d/0x100 arch/x86/kernel/apic/apic.c:1096
+ asm_sysvec_apic_timer_interrupt+0x12/0x20 arch/x86/include/asm/idtentry.h:628
+RIP: 0010:native_save_fl arch/x86/include/asm/irqflags.h:29 [inline]
+RIP: 0010:arch_local_save_flags arch/x86/include/asm/irqflags.h:79 [inline]
+RIP: 0010:arch_irqs_disabled arch/x86/include/asm/irqflags.h:169 [inline]
+RIP: 0010:acpi_safe_halt drivers/acpi/processor_idle.c:111 [inline]
+RIP: 0010:acpi_idle_do_entry+0x1c9/0x250 drivers/acpi/processor_idle.c:516
+
+Fixes: 1c0d32fde5bd ("net_sched: gen_estimator: complete rewrite of rate estimators")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Link: https://lore.kernel.org/r/20210114181929.1717985-1-eric.dumazet@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[sudip: adjust context]
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/gen_estimator.c |   11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/net/core/gen_estimator.c
++++ b/net/core/gen_estimator.c
+@@ -84,11 +84,11 @@ static void est_timer(struct timer_list
+       u64 rate, brate;
+       est_fetch_counters(est, &b);
+-      brate = (b.bytes - est->last_bytes) << (10 - est->ewma_log - est->intvl_log);
+-      brate -= (est->avbps >> est->ewma_log);
++      brate = (b.bytes - est->last_bytes) << (10 - est->intvl_log);
++      brate = (brate >> est->ewma_log) - (est->avbps >> est->ewma_log);
+-      rate = (u64)(b.packets - est->last_packets) << (10 - est->ewma_log - est->intvl_log);
+-      rate -= (est->avpps >> est->ewma_log);
++      rate = (u64)(b.packets - est->last_packets) << (10 - est->intvl_log);
++      rate = (rate >> est->ewma_log) - (est->avpps >> est->ewma_log);
+       write_seqcount_begin(&est->seq);
+       est->avbps += brate;
+@@ -147,6 +147,9 @@ int gen_new_estimator(struct gnet_stats_
+       if (parm->interval < -2 || parm->interval > 3)
+               return -EINVAL;
++      if (parm->ewma_log == 0 || parm->ewma_log >= 31)
++              return -EINVAL;
++
+       est = kzalloc(sizeof(*est), GFP_KERNEL);
+       if (!est)
+               return -ENOBUFS;
index 279c89515fae8ded34f9132231186a4e9f8069db..7ceb62227a006ce8b1b25ca0289cc7dc4f533795 100644 (file)
@@ -1,3 +1,5 @@
 net-dsa-bcm_sf2-put-device-node-before-return.patch
 ibmvnic-ensure-that-crq-entry-read-are-correctly-ordered.patch
 acpi-thermal-do-not-call-acpi_thermal_check-directly.patch
+sysctl-handle-overflow-in-proc_get_long.patch
+net_sched-gen_estimator-support-large-ewma-log.patch
diff --git a/queue-4.19/sysctl-handle-overflow-in-proc_get_long.patch b/queue-4.19/sysctl-handle-overflow-in-proc_get_long.patch
new file mode 100644 (file)
index 0000000..19ae531
--- /dev/null
@@ -0,0 +1,120 @@
+From 7f2923c4f73f21cfd714d12a2d48de8c21f11cfe Mon Sep 17 00:00:00 2001
+From: Christian Brauner <christian@brauner.io>
+Date: Thu, 7 Mar 2019 16:29:40 -0800
+Subject: sysctl: handle overflow in proc_get_long
+
+From: Christian Brauner <christian@brauner.io>
+
+commit 7f2923c4f73f21cfd714d12a2d48de8c21f11cfe upstream.
+
+proc_get_long() is a funny function.  It uses simple_strtoul() and for a
+good reason.  proc_get_long() wants to always succeed the parse and
+return the maybe incorrect value and the trailing characters to check
+against a pre-defined list of acceptable trailing values.  However,
+simple_strtoul() explicitly ignores overflows which can cause funny
+things like the following to happen:
+
+  echo 18446744073709551616 > /proc/sys/fs/file-max
+  cat /proc/sys/fs/file-max
+  0
+
+(Which will cause your system to silently die behind your back.)
+
+On the other hand kstrtoul() does do overflow detection but does not
+return the trailing characters, and also fails the parse when anything
+other than '\n' is a trailing character whereas proc_get_long() wants to
+be more lenient.
+
+Now, before adding another kstrtoul() function let's simply add a static
+parse strtoul_lenient() which:
+ - fails on overflow with -ERANGE
+ - returns the trailing characters to the caller
+
+The reason why we should fail on ERANGE is that we already do a partial
+fail on overflow right now.  Namely, when the TMPBUFLEN is exceeded.  So
+we already reject values such as 184467440737095516160 (21 chars) but
+accept values such as 18446744073709551616 (20 chars) but both are
+overflows.  So we should just always reject 64bit overflows and not
+special-case this based on the number of chars.
+
+Link: http://lkml.kernel.org/r/20190107222700.15954-2-christian@brauner.io
+Signed-off-by: Christian Brauner <christian@brauner.io>
+Acked-by: Kees Cook <keescook@chromium.org>
+Cc: "Eric W. Biederman" <ebiederm@xmission.com>
+Cc: Luis Chamberlain <mcgrof@kernel.org>
+Cc: Joe Lawrence <joe.lawrence@redhat.com>
+Cc: Waiman Long <longman@redhat.com>
+Cc: Dominik Brodowski <linux@dominikbrodowski.net>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Alexey Dobriyan <adobriyan@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Joerg Vehlow <lkml@jv-coder.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/sysctl.c |   40 +++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 39 insertions(+), 1 deletion(-)
+
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -68,6 +68,8 @@
+ #include <linux/mount.h>
+ #include <linux/pipe_fs_i.h>
++#include "../lib/kstrtox.h"
++
+ #include <linux/uaccess.h>
+ #include <asm/processor.h>
+@@ -2069,6 +2071,41 @@ static void proc_skip_char(char **buf, s
+       }
+ }
++/**
++ * strtoul_lenient - parse an ASCII formatted integer from a buffer and only
++ *                   fail on overflow
++ *
++ * @cp: kernel buffer containing the string to parse
++ * @endp: pointer to store the trailing characters
++ * @base: the base to use
++ * @res: where the parsed integer will be stored
++ *
++ * In case of success 0 is returned and @res will contain the parsed integer,
++ * @endp will hold any trailing characters.
++ * This function will fail the parse on overflow. If there wasn't an overflow
++ * the function will defer the decision what characters count as invalid to the
++ * caller.
++ */
++static int strtoul_lenient(const char *cp, char **endp, unsigned int base,
++                         unsigned long *res)
++{
++      unsigned long long result;
++      unsigned int rv;
++
++      cp = _parse_integer_fixup_radix(cp, &base);
++      rv = _parse_integer(cp, base, &result);
++      if ((rv & KSTRTOX_OVERFLOW) || (result != (unsigned long)result))
++              return -ERANGE;
++
++      cp += rv;
++
++      if (endp)
++              *endp = (char *)cp;
++
++      *res = (unsigned long)result;
++      return 0;
++}
++
+ #define TMPBUFLEN 22
+ /**
+  * proc_get_long - reads an ASCII formatted integer from a user buffer
+@@ -2112,7 +2149,8 @@ static int proc_get_long(char **buf, siz
+       if (!isdigit(*p))
+               return -EINVAL;
+-      *val = simple_strtoul(p, &p, 0);
++      if (strtoul_lenient(p, &p, 0, val))
++              return -EINVAL;
+       len = p - tmp;