--- /dev/null
+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;
--- /dev/null
+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;
+