From: Greg Kroah-Hartman Date: Fri, 5 Feb 2021 09:02:29 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v4.4.256~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=51adc443e9ddb42f7e5b134a73fdd233c17e6a76;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: net_sched-gen_estimator-support-large-ewma-log.patch sysctl-handle-overflow-in-proc_get_long.patch --- 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 index 00000000000..ed0b0757eb3 --- /dev/null +++ b/queue-4.19/net_sched-gen_estimator-support-large-ewma-log.patch @@ -0,0 +1,90 @@ +From foo@baz Fri Feb 5 09:57:03 AM CET 2021 +From: Eric Dumazet +Date: Thu, 14 Jan 2021 10:19:29 -0800 +Subject: net_sched: gen_estimator: support large ewma log + +From: Eric Dumazet + +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: + + __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 + + __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 +Reported-by: syzbot +Link: https://lore.kernel.org/r/20210114181929.1717985-1-eric.dumazet@gmail.com +Signed-off-by: Jakub Kicinski +[sudip: adjust context] +Signed-off-by: Sudip Mukherjee +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-4.19/series b/queue-4.19/series index 279c89515fa..7ceb62227a0 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -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 index 00000000000..19ae53104e5 --- /dev/null +++ b/queue-4.19/sysctl-handle-overflow-in-proc_get_long.patch @@ -0,0 +1,120 @@ +From 7f2923c4f73f21cfd714d12a2d48de8c21f11cfe Mon Sep 17 00:00:00 2001 +From: Christian Brauner +Date: Thu, 7 Mar 2019 16:29:40 -0800 +Subject: sysctl: handle overflow in proc_get_long + +From: Christian Brauner + +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 +Acked-by: Kees Cook +Cc: "Eric W. Biederman" +Cc: Luis Chamberlain +Cc: Joe Lawrence +Cc: Waiman Long +Cc: Dominik Brodowski +Cc: Al Viro +Cc: Alexey Dobriyan +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Joerg Vehlow +Signed-off-by: Greg Kroah-Hartman +--- + kernel/sysctl.c | 40 +++++++++++++++++++++++++++++++++++++++- + 1 file changed, 39 insertions(+), 1 deletion(-) + +--- a/kernel/sysctl.c ++++ b/kernel/sysctl.c +@@ -68,6 +68,8 @@ + #include + #include + ++#include "../lib/kstrtox.h" ++ + #include + #include + +@@ -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; +