]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 1 Mar 2021 14:54:18 +0000 (15:54 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 1 Mar 2021 14:54:18 +0000 (15:54 +0100)
added patches:
ipv6-icmp6-avoid-indirect-call-for-icmpv6_send.patch
ipv6-silence-compilation-warning-for-non-ipv6-builds.patch
net-icmp-pass-zeroed-opts-from-icmp-v6-_ndo_send-before-sending.patch
net-sched-fix-police-ext-initialization.patch

queue-5.4/ipv6-icmp6-avoid-indirect-call-for-icmpv6_send.patch [new file with mode: 0644]
queue-5.4/ipv6-silence-compilation-warning-for-non-ipv6-builds.patch [new file with mode: 0644]
queue-5.4/net-icmp-pass-zeroed-opts-from-icmp-v6-_ndo_send-before-sending.patch [new file with mode: 0644]
queue-5.4/net-sched-fix-police-ext-initialization.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/ipv6-icmp6-avoid-indirect-call-for-icmpv6_send.patch b/queue-5.4/ipv6-icmp6-avoid-indirect-call-for-icmpv6_send.patch
new file mode 100644 (file)
index 0000000..56c61b6
--- /dev/null
@@ -0,0 +1,106 @@
+From cc7a21b6fbd945f8d8f61422ccd27203c1fafeb7 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Fri, 19 Jun 2020 12:02:59 -0700
+Subject: ipv6: icmp6: avoid indirect call for icmpv6_send()
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit cc7a21b6fbd945f8d8f61422ccd27203c1fafeb7 upstream.
+
+If IPv6 is builtin, we do not need an expensive indirect call
+to reach icmp6_send().
+
+v2: put inline keyword before the type to avoid sparse warnings.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/icmpv6.h |   22 +++++++++++++++++++++-
+ net/ipv6/icmp.c        |    5 +++--
+ net/ipv6/ip6_icmp.c    |    9 +++++----
+ 3 files changed, 29 insertions(+), 7 deletions(-)
+
+--- a/include/linux/icmpv6.h
++++ b/include/linux/icmpv6.h
+@@ -13,12 +13,32 @@ static inline struct icmp6hdr *icmp6_hdr
+ #include <linux/netdevice.h>
+ #if IS_ENABLED(CONFIG_IPV6)
+-extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
+ typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+                            const struct in6_addr *force_saddr);
++#if IS_BUILTIN(CONFIG_IPV6)
++void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
++              const struct in6_addr *force_saddr);
++static inline void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
++{
++      icmp6_send(skb, type, code, info, NULL);
++}
++static inline int inet6_register_icmp_sender(ip6_icmp_send_t *fn)
++{
++      BUILD_BUG_ON(fn != icmp6_send);
++      return 0;
++}
++static inline int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn)
++{
++      BUILD_BUG_ON(fn != icmp6_send);
++      return 0;
++}
++#else
++extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
+ extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
+ extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
++#endif
++
+ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
+                              unsigned int data_len);
+--- a/net/ipv6/icmp.c
++++ b/net/ipv6/icmp.c
+@@ -426,8 +426,8 @@ static int icmp6_iif(const struct sk_buf
+ /*
+  *    Send an ICMP message in response to a packet in error
+  */
+-static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+-                     const struct in6_addr *force_saddr)
++void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
++              const struct in6_addr *force_saddr)
+ {
+       struct inet6_dev *idev = NULL;
+       struct ipv6hdr *hdr = ipv6_hdr(skb);
+@@ -600,6 +600,7 @@ out:
+ out_bh_enable:
+       local_bh_enable();
+ }
++EXPORT_SYMBOL(icmp6_send);
+ /* Slightly more convenient version of icmp6_send.
+  */
+--- a/net/ipv6/ip6_icmp.c
++++ b/net/ipv6/ip6_icmp.c
+@@ -9,6 +9,8 @@
+ #if IS_ENABLED(CONFIG_IPV6)
++#if !IS_BUILTIN(CONFIG_IPV6)
++
+ static ip6_icmp_send_t __rcu *ip6_icmp_send;
+ int inet6_register_icmp_sender(ip6_icmp_send_t *fn)
+@@ -38,11 +40,10 @@ void icmpv6_send(struct sk_buff *skb, u8
+       rcu_read_lock();
+       send = rcu_dereference(ip6_icmp_send);
+-      if (!send)
+-              goto out;
+-      send(skb, type, code, info, NULL);
+-out:
++      if (send)
++              send(skb, type, code, info, NULL);
+       rcu_read_unlock();
+ }
+ EXPORT_SYMBOL(icmpv6_send);
+ #endif
++#endif
diff --git a/queue-5.4/ipv6-silence-compilation-warning-for-non-ipv6-builds.patch b/queue-5.4/ipv6-silence-compilation-warning-for-non-ipv6-builds.patch
new file mode 100644 (file)
index 0000000..d2b5173
--- /dev/null
@@ -0,0 +1,37 @@
+From 1faba27f11c8da244e793546a1b35a9b1da8208e Mon Sep 17 00:00:00 2001
+From: Leon Romanovsky <leonro@nvidia.com>
+Date: Wed, 3 Feb 2021 15:51:09 +0200
+Subject: ipv6: silence compilation warning for non-IPV6 builds
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+commit 1faba27f11c8da244e793546a1b35a9b1da8208e upstream.
+
+The W=1 compilation of allmodconfig generates the following warning:
+
+net/ipv6/icmp.c:448:6: warning: no previous prototype for 'icmp6_send' [-Wmissing-prototypes]
+  448 | void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+      |      ^~~~~~~~~~
+
+Fix it by providing function declaration for builds with ipv6 as a module.
+
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/icmpv6.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/linux/icmpv6.h
++++ b/include/linux/icmpv6.h
+@@ -16,9 +16,9 @@ static inline struct icmp6hdr *icmp6_hdr
+ typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+                            const struct in6_addr *force_saddr);
+-#if IS_BUILTIN(CONFIG_IPV6)
+ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+               const struct in6_addr *force_saddr);
++#if IS_BUILTIN(CONFIG_IPV6)
+ static inline void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
+ {
+       icmp6_send(skb, type, code, info, NULL);
diff --git a/queue-5.4/net-icmp-pass-zeroed-opts-from-icmp-v6-_ndo_send-before-sending.patch b/queue-5.4/net-icmp-pass-zeroed-opts-from-icmp-v6-_ndo_send-before-sending.patch
new file mode 100644 (file)
index 0000000..969f87e
--- /dev/null
@@ -0,0 +1,248 @@
+From ee576c47db60432c37e54b1e2b43a8ca6d3a8dca Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Tue, 23 Feb 2021 14:18:58 +0100
+Subject: net: icmp: pass zeroed opts from icmp{,v6}_ndo_send before sending
+
+From: Jason A. Donenfeld <Jason@zx2c4.com>
+
+commit ee576c47db60432c37e54b1e2b43a8ca6d3a8dca upstream.
+
+The icmp{,v6}_send functions make all sorts of use of skb->cb, casting
+it with IPCB or IP6CB, assuming the skb to have come directly from the
+inet layer. But when the packet comes from the ndo layer, especially
+when forwarded, there's no telling what might be in skb->cb at that
+point. As a result, the icmp sending code risks reading bogus memory
+contents, which can result in nasty stack overflows such as this one
+reported by a user:
+
+    panic+0x108/0x2ea
+    __stack_chk_fail+0x14/0x20
+    __icmp_send+0x5bd/0x5c0
+    icmp_ndo_send+0x148/0x160
+
+In icmp_send, skb->cb is cast with IPCB and an ip_options struct is read
+from it. The optlen parameter there is of particular note, as it can
+induce writes beyond bounds. There are quite a few ways that can happen
+in __ip_options_echo. For example:
+
+    // sptr/skb are attacker-controlled skb bytes
+    sptr = skb_network_header(skb);
+    // dptr/dopt points to stack memory allocated by __icmp_send
+    dptr = dopt->__data;
+    // sopt is the corrupt skb->cb in question
+    if (sopt->rr) {
+        optlen  = sptr[sopt->rr+1]; // corrupt skb->cb + skb->data
+        soffset = sptr[sopt->rr+2]; // corrupt skb->cb + skb->data
+       // this now writes potentially attacker-controlled data, over
+       // flowing the stack:
+        memcpy(dptr, sptr+sopt->rr, optlen);
+    }
+
+In the icmpv6_send case, the story is similar, but not as dire, as only
+IP6CB(skb)->iif and IP6CB(skb)->dsthao are used. The dsthao case is
+worse than the iif case, but it is passed to ipv6_find_tlv, which does
+a bit of bounds checking on the value.
+
+This is easy to simulate by doing a `memset(skb->cb, 0x41,
+sizeof(skb->cb));` before calling icmp{,v6}_ndo_send, and it's only by
+good fortune and the rarity of icmp sending from that context that we've
+avoided reports like this until now. For example, in KASAN:
+
+    BUG: KASAN: stack-out-of-bounds in __ip_options_echo+0xa0e/0x12b0
+    Write of size 38 at addr ffff888006f1f80e by task ping/89
+    CPU: 2 PID: 89 Comm: ping Not tainted 5.10.0-rc7-debug+ #5
+    Call Trace:
+     dump_stack+0x9a/0xcc
+     print_address_description.constprop.0+0x1a/0x160
+     __kasan_report.cold+0x20/0x38
+     kasan_report+0x32/0x40
+     check_memory_region+0x145/0x1a0
+     memcpy+0x39/0x60
+     __ip_options_echo+0xa0e/0x12b0
+     __icmp_send+0x744/0x1700
+
+Actually, out of the 4 drivers that do this, only gtp zeroed the cb for
+the v4 case, while the rest did not. So this commit actually removes the
+gtp-specific zeroing, while putting the code where it belongs in the
+shared infrastructure of icmp{,v6}_ndo_send.
+
+This commit fixes the issue by passing an empty IPCB or IP6CB along to
+the functions that actually do the work. For the icmp_send, this was
+already trivial, thanks to __icmp_send providing the plumbing function.
+For icmpv6_send, this required a tiny bit of refactoring to make it
+behave like the v4 case, after which it was straight forward.
+
+Fixes: a2b78e9b2cac ("sunvnet: generate ICMP PTMUD messages for smaller port MTUs")
+Reported-by: SinYu <liuxyon@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://lore.kernel.org/netdev/CAF=yD-LOF116aHub6RMe8vB8ZpnrrnoTdqhobEx+bvoA8AsP0w@mail.gmail.com/T/
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Link: https://lore.kernel.org/r/20210223131858.72082-1-Jason@zx2c4.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/gtp.c      |    1 -
+ include/linux/icmpv6.h |   20 +++++++++++++++-----
+ include/linux/ipv6.h   |    1 -
+ net/ipv6/icmp.c        |   16 ++++++++--------
+ net/ipv6/ip6_icmp.c    |    7 ++++---
+ 5 files changed, 27 insertions(+), 18 deletions(-)
+
+--- a/drivers/net/gtp.c
++++ b/drivers/net/gtp.c
+@@ -545,7 +545,6 @@ static int gtp_build_skb_ip4(struct sk_b
+       if (!skb_is_gso(skb) && (iph->frag_off & htons(IP_DF)) &&
+           mtu < ntohs(iph->tot_len)) {
+               netdev_dbg(dev, "packet too big, fragmentation needed\n");
+-              memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
+               icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
+                         htonl(mtu));
+               goto err_rt;
+--- a/include/linux/icmpv6.h
++++ b/include/linux/icmpv6.h
+@@ -3,6 +3,7 @@
+ #define _LINUX_ICMPV6_H
+ #include <linux/skbuff.h>
++#include <linux/ipv6.h>
+ #include <uapi/linux/icmpv6.h>
+ static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb)
+@@ -15,13 +16,16 @@ static inline struct icmp6hdr *icmp6_hdr
+ #if IS_ENABLED(CONFIG_IPV6)
+ typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+-                           const struct in6_addr *force_saddr);
++                           const struct in6_addr *force_saddr,
++                           const struct inet6_skb_parm *parm);
+ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+-              const struct in6_addr *force_saddr);
++              const struct in6_addr *force_saddr,
++              const struct inet6_skb_parm *parm);
+ #if IS_BUILTIN(CONFIG_IPV6)
+-static inline void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
++static inline void __icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
++                               const struct inet6_skb_parm *parm)
+ {
+-      icmp6_send(skb, type, code, info, NULL);
++      icmp6_send(skb, type, code, info, NULL, parm);
+ }
+ static inline int inet6_register_icmp_sender(ip6_icmp_send_t *fn)
+ {
+@@ -34,11 +38,17 @@ static inline int inet6_unregister_icmp_
+       return 0;
+ }
+ #else
+-extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
++extern void __icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
++                        const struct inet6_skb_parm *parm);
+ extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
+ extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
+ #endif
++static inline void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
++{
++      __icmpv6_send(skb, type, code, info, IP6CB(skb));
++}
++
+ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
+                              unsigned int data_len);
+--- a/include/linux/ipv6.h
++++ b/include/linux/ipv6.h
+@@ -83,7 +83,6 @@ struct ipv6_params {
+       __s32 autoconf;
+ };
+ extern struct ipv6_params ipv6_defaults;
+-#include <linux/icmpv6.h>
+ #include <linux/tcp.h>
+ #include <linux/udp.h>
+--- a/net/ipv6/icmp.c
++++ b/net/ipv6/icmp.c
+@@ -312,10 +312,9 @@ static int icmpv6_getfrag(void *from, ch
+ }
+ #if IS_ENABLED(CONFIG_IPV6_MIP6)
+-static void mip6_addr_swap(struct sk_buff *skb)
++static void mip6_addr_swap(struct sk_buff *skb, const struct inet6_skb_parm *opt)
+ {
+       struct ipv6hdr *iph = ipv6_hdr(skb);
+-      struct inet6_skb_parm *opt = IP6CB(skb);
+       struct ipv6_destopt_hao *hao;
+       struct in6_addr tmp;
+       int off;
+@@ -332,7 +331,7 @@ static void mip6_addr_swap(struct sk_buf
+       }
+ }
+ #else
+-static inline void mip6_addr_swap(struct sk_buff *skb) {}
++static inline void mip6_addr_swap(struct sk_buff *skb, const struct inet6_skb_parm *opt) {}
+ #endif
+ static struct dst_entry *icmpv6_route_lookup(struct net *net,
+@@ -427,7 +426,8 @@ static int icmp6_iif(const struct sk_buf
+  *    Send an ICMP message in response to a packet in error
+  */
+ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+-              const struct in6_addr *force_saddr)
++              const struct in6_addr *force_saddr,
++              const struct inet6_skb_parm *parm)
+ {
+       struct inet6_dev *idev = NULL;
+       struct ipv6hdr *hdr = ipv6_hdr(skb);
+@@ -520,7 +520,7 @@ void icmp6_send(struct sk_buff *skb, u8
+       if (!(skb->dev->flags & IFF_LOOPBACK) && !icmpv6_global_allow(net, type))
+               goto out_bh_enable;
+-      mip6_addr_swap(skb);
++      mip6_addr_swap(skb, parm);
+       memset(&fl6, 0, sizeof(fl6));
+       fl6.flowi6_proto = IPPROTO_ICMPV6;
+@@ -606,7 +606,7 @@ EXPORT_SYMBOL(icmp6_send);
+  */
+ void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
+ {
+-      icmp6_send(skb, ICMPV6_PARAMPROB, code, pos, NULL);
++      icmp6_send(skb, ICMPV6_PARAMPROB, code, pos, NULL, IP6CB(skb));
+       kfree_skb(skb);
+ }
+@@ -663,10 +663,10 @@ int ip6_err_gen_icmpv6_unreach(struct sk
+       }
+       if (type == ICMP_TIME_EXCEEDED)
+               icmp6_send(skb2, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
+-                         info, &temp_saddr);
++                         info, &temp_saddr, IP6CB(skb2));
+       else
+               icmp6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH,
+-                         info, &temp_saddr);
++                         info, &temp_saddr, IP6CB(skb2));
+       if (rt)
+               ip6_rt_put(rt);
+--- a/net/ipv6/ip6_icmp.c
++++ b/net/ipv6/ip6_icmp.c
+@@ -33,7 +33,8 @@ int inet6_unregister_icmp_sender(ip6_icm
+ }
+ EXPORT_SYMBOL(inet6_unregister_icmp_sender);
+-void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
++void __icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
++                 const struct inet6_skb_parm *parm)
+ {
+       ip6_icmp_send_t *send;
+@@ -41,9 +42,9 @@ void icmpv6_send(struct sk_buff *skb, u8
+       send = rcu_dereference(ip6_icmp_send);
+       if (send)
+-              send(skb, type, code, info, NULL);
++              send(skb, type, code, info, NULL, parm);
+       rcu_read_unlock();
+ }
+-EXPORT_SYMBOL(icmpv6_send);
++EXPORT_SYMBOL(__icmpv6_send);
+ #endif
+ #endif
diff --git a/queue-5.4/net-sched-fix-police-ext-initialization.patch b/queue-5.4/net-sched-fix-police-ext-initialization.patch
new file mode 100644 (file)
index 0000000..f32ee82
--- /dev/null
@@ -0,0 +1,119 @@
+From 396d7f23adf9e8c436dd81a69488b5b6a865acf8 Mon Sep 17 00:00:00 2001
+From: Vlad Buslov <vladbu@nvidia.com>
+Date: Tue, 16 Feb 2021 18:22:00 +0200
+Subject: net: sched: fix police ext initialization
+
+From: Vlad Buslov <vladbu@nvidia.com>
+
+commit 396d7f23adf9e8c436dd81a69488b5b6a865acf8 upstream.
+
+When police action is created by cls API tcf_exts_validate() first
+conditional that calls tcf_action_init_1() directly, the action idr is not
+updated according to latest changes in action API that require caller to
+commit newly created action to idr with tcf_idr_insert_many(). This results
+such action not being accessible through act API and causes crash reported
+by syzbot:
+
+==================================================================
+BUG: KASAN: null-ptr-deref in instrument_atomic_read include/linux/instrumented.h:71 [inline]
+BUG: KASAN: null-ptr-deref in atomic_read include/asm-generic/atomic-instrumented.h:27 [inline]
+BUG: KASAN: null-ptr-deref in __tcf_idr_release net/sched/act_api.c:178 [inline]
+BUG: KASAN: null-ptr-deref in tcf_idrinfo_destroy+0x129/0x1d0 net/sched/act_api.c:598
+Read of size 4 at addr 0000000000000010 by task kworker/u4:5/204
+
+CPU: 0 PID: 204 Comm: kworker/u4:5 Not tainted 5.11.0-rc7-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Workqueue: netns cleanup_net
+Call Trace:
+ __dump_stack lib/dump_stack.c:79 [inline]
+ dump_stack+0x107/0x163 lib/dump_stack.c:120
+ __kasan_report mm/kasan/report.c:400 [inline]
+ kasan_report.cold+0x5f/0xd5 mm/kasan/report.c:413
+ check_memory_region_inline mm/kasan/generic.c:179 [inline]
+ check_memory_region+0x13d/0x180 mm/kasan/generic.c:185
+ instrument_atomic_read include/linux/instrumented.h:71 [inline]
+ atomic_read include/asm-generic/atomic-instrumented.h:27 [inline]
+ __tcf_idr_release net/sched/act_api.c:178 [inline]
+ tcf_idrinfo_destroy+0x129/0x1d0 net/sched/act_api.c:598
+ tc_action_net_exit include/net/act_api.h:151 [inline]
+ police_exit_net+0x168/0x360 net/sched/act_police.c:390
+ ops_exit_list+0x10d/0x160 net/core/net_namespace.c:190
+ cleanup_net+0x4ea/0xb10 net/core/net_namespace.c:604
+ process_one_work+0x98d/0x15f0 kernel/workqueue.c:2275
+ worker_thread+0x64c/0x1120 kernel/workqueue.c:2421
+ kthread+0x3b1/0x4a0 kernel/kthread.c:292
+ ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:296
+==================================================================
+Kernel panic - not syncing: panic_on_warn set ...
+CPU: 0 PID: 204 Comm: kworker/u4:5 Tainted: G    B             5.11.0-rc7-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Workqueue: netns cleanup_net
+Call Trace:
+ __dump_stack lib/dump_stack.c:79 [inline]
+ dump_stack+0x107/0x163 lib/dump_stack.c:120
+ panic+0x306/0x73d kernel/panic.c:231
+ end_report+0x58/0x5e mm/kasan/report.c:100
+ __kasan_report mm/kasan/report.c:403 [inline]
+ kasan_report.cold+0x67/0xd5 mm/kasan/report.c:413
+ check_memory_region_inline mm/kasan/generic.c:179 [inline]
+ check_memory_region+0x13d/0x180 mm/kasan/generic.c:185
+ instrument_atomic_read include/linux/instrumented.h:71 [inline]
+ atomic_read include/asm-generic/atomic-instrumented.h:27 [inline]
+ __tcf_idr_release net/sched/act_api.c:178 [inline]
+ tcf_idrinfo_destroy+0x129/0x1d0 net/sched/act_api.c:598
+ tc_action_net_exit include/net/act_api.h:151 [inline]
+ police_exit_net+0x168/0x360 net/sched/act_police.c:390
+ ops_exit_list+0x10d/0x160 net/core/net_namespace.c:190
+ cleanup_net+0x4ea/0xb10 net/core/net_namespace.c:604
+ process_one_work+0x98d/0x15f0 kernel/workqueue.c:2275
+ worker_thread+0x64c/0x1120 kernel/workqueue.c:2421
+ kthread+0x3b1/0x4a0 kernel/kthread.c:292
+ ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:296
+Kernel Offset: disabled
+
+Fix the issue by calling tcf_idr_insert_many() after successful action
+initialization.
+
+Fixes: 0fedc63fadf0 ("net_sched: commit action insertions together")
+Reported-by: syzbot+151e3e714d34ae4ce7e8@syzkaller.appspotmail.com
+Signed-off-by: Vlad Buslov <vladbu@nvidia.com>
+Reviewed-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/act_api.h |    1 +
+ net/sched/act_api.c   |    2 +-
+ net/sched/cls_api.c   |    1 +
+ 3 files changed, 3 insertions(+), 1 deletion(-)
+
+--- a/include/net/act_api.h
++++ b/include/net/act_api.h
+@@ -156,6 +156,7 @@ int tcf_idr_search(struct tc_action_net
+ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
+                  struct tc_action **a, const struct tc_action_ops *ops,
+                  int bind, bool cpustats);
++void tcf_idr_insert_many(struct tc_action *actions[]);
+ void tcf_idr_cleanup(struct tc_action_net *tn, u32 index);
+ int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index,
+                       struct tc_action **a, int bind);
+--- a/net/sched/act_api.c
++++ b/net/sched/act_api.c
+@@ -823,7 +823,7 @@ static const struct nla_policy tcf_actio
+       [TCA_ACT_OPTIONS]       = { .type = NLA_NESTED },
+ };
+-static void tcf_idr_insert_many(struct tc_action *actions[])
++void tcf_idr_insert_many(struct tc_action *actions[])
+ {
+       int i;
+--- a/net/sched/cls_api.c
++++ b/net/sched/cls_api.c
+@@ -3026,6 +3026,7 @@ int tcf_exts_validate(struct net *net, s
+                       act->type = exts->type = TCA_OLD_COMPAT;
+                       exts->actions[0] = act;
+                       exts->nr_actions = 1;
++                      tcf_idr_insert_many(exts->actions);
+               } else if (exts->action && tb[exts->action]) {
+                       int err;
index 4672733967076699f1ef1d8ba8bdfcc1b4dba5ba..4df8f4301ac5de9d6c70466dccc32bdb1560c9c8 100644 (file)
@@ -328,3 +328,7 @@ dm-era-use-correct-value-size-in-equality-function-of-writeset-tree.patch
 dm-era-reinitialize-bitset-cache-before-digesting-a-new-writeset.patch
 dm-era-only-resize-metadata-in-preresume.patch
 drm-i915-reject-446-480mhz-hdmi-clock-on-glk.patch
+ipv6-icmp6-avoid-indirect-call-for-icmpv6_send.patch
+ipv6-silence-compilation-warning-for-non-ipv6-builds.patch
+net-icmp-pass-zeroed-opts-from-icmp-v6-_ndo_send-before-sending.patch
+net-sched-fix-police-ext-initialization.patch