]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.3-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Nov 2019 10:50:20 +0000 (11:50 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Nov 2019 10:50:20 +0000 (11:50 +0100)
added patches:
batman-adv-avoid-free-alloc-race-when-handling-ogm-buffer.patch
blackhole_netdev-fix-syzkaller-reported-issue.patch
bonding-fix-potential-null-deref-in-bond_update_slave_arr.patch
llc-fix-sk_buff-leak-in-llc_conn_service.patch
llc-fix-sk_buff-leak-in-llc_sap_state_process.patch
net-sched-sch_sfb-don-t-call-qdisc_put-while-holding-tree-lock.patch
net-usb-sr9800-fix-uninitialized-local-variable.patch
netfilter-conntrack-avoid-possible-false-sharing.patch
nfc-pn533-fix-use-after-free-and-memleaks.patch
rxrpc-fix-call-ref-leak.patch
rxrpc-fix-trace-after-put-looking-at-the-put-peer-record.patch
rxrpc-rxrpc_peer-needs-to-hold-a-ref-on-the-rxrpc_local-record.patch
sch_netem-fix-rcu-splat-in-netem_enqueue.patch

14 files changed:
queue-5.3/batman-adv-avoid-free-alloc-race-when-handling-ogm-buffer.patch [new file with mode: 0644]
queue-5.3/blackhole_netdev-fix-syzkaller-reported-issue.patch [new file with mode: 0644]
queue-5.3/bonding-fix-potential-null-deref-in-bond_update_slave_arr.patch [new file with mode: 0644]
queue-5.3/llc-fix-sk_buff-leak-in-llc_conn_service.patch [new file with mode: 0644]
queue-5.3/llc-fix-sk_buff-leak-in-llc_sap_state_process.patch [new file with mode: 0644]
queue-5.3/net-sched-sch_sfb-don-t-call-qdisc_put-while-holding-tree-lock.patch [new file with mode: 0644]
queue-5.3/net-usb-sr9800-fix-uninitialized-local-variable.patch [new file with mode: 0644]
queue-5.3/netfilter-conntrack-avoid-possible-false-sharing.patch [new file with mode: 0644]
queue-5.3/nfc-pn533-fix-use-after-free-and-memleaks.patch [new file with mode: 0644]
queue-5.3/rxrpc-fix-call-ref-leak.patch [new file with mode: 0644]
queue-5.3/rxrpc-fix-trace-after-put-looking-at-the-put-peer-record.patch [new file with mode: 0644]
queue-5.3/rxrpc-rxrpc_peer-needs-to-hold-a-ref-on-the-rxrpc_local-record.patch [new file with mode: 0644]
queue-5.3/sch_netem-fix-rcu-splat-in-netem_enqueue.patch [new file with mode: 0644]
queue-5.3/series

diff --git a/queue-5.3/batman-adv-avoid-free-alloc-race-when-handling-ogm-buffer.patch b/queue-5.3/batman-adv-avoid-free-alloc-race-when-handling-ogm-buffer.patch
new file mode 100644 (file)
index 0000000..cec5a49
--- /dev/null
@@ -0,0 +1,200 @@
+From 40e220b4218bb3d278e5e8cc04ccdfd1c7ff8307 Mon Sep 17 00:00:00 2001
+From: Sven Eckelmann <sven@narfation.org>
+Date: Thu, 3 Oct 2019 17:02:01 +0200
+Subject: batman-adv: Avoid free/alloc race when handling OGM buffer
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 40e220b4218bb3d278e5e8cc04ccdfd1c7ff8307 upstream.
+
+Each slave interface of an B.A.T.M.A.N. IV virtual interface has an OGM
+packet buffer which is initialized using data from netdevice notifier and
+other rtnetlink related hooks. It is sent regularly via various slave
+interfaces of the batadv virtual interface and in this process also
+modified (realloced) to integrate additional state information via TVLV
+containers.
+
+It must be avoided that the worker item is executed without a common lock
+with the netdevice notifier/rtnetlink helpers. Otherwise it can either
+happen that half modified/freed data is sent out or functions modifying the
+OGM buffer try to access already freed memory regions.
+
+Reported-by: syzbot+0cc629f19ccb8534935b@syzkaller.appspotmail.com
+Fixes: c6c8fea29769 ("net: Add batman-adv meshing protocol")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/batman-adv/bat_iv_ogm.c     |   61 ++++++++++++++++++++++++++++++++++------
+ net/batman-adv/hard-interface.c |    2 +
+ net/batman-adv/types.h          |    3 +
+ 3 files changed, 57 insertions(+), 9 deletions(-)
+
+--- a/net/batman-adv/bat_iv_ogm.c
++++ b/net/batman-adv/bat_iv_ogm.c
+@@ -22,6 +22,8 @@
+ #include <linux/kernel.h>
+ #include <linux/kref.h>
+ #include <linux/list.h>
++#include <linux/lockdep.h>
++#include <linux/mutex.h>
+ #include <linux/netdevice.h>
+ #include <linux/netlink.h>
+ #include <linux/pkt_sched.h>
+@@ -193,14 +195,18 @@ static int batadv_iv_ogm_iface_enable(st
+       unsigned char *ogm_buff;
+       u32 random_seqno;
++      mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
++
+       /* randomize initial seqno to avoid collision */
+       get_random_bytes(&random_seqno, sizeof(random_seqno));
+       atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);
+       hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN;
+       ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC);
+-      if (!ogm_buff)
++      if (!ogm_buff) {
++              mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
+               return -ENOMEM;
++      }
+       hard_iface->bat_iv.ogm_buff = ogm_buff;
+@@ -212,35 +218,59 @@ static int batadv_iv_ogm_iface_enable(st
+       batadv_ogm_packet->reserved = 0;
+       batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
++      mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
++
+       return 0;
+ }
+ static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
+ {
++      mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
++
+       kfree(hard_iface->bat_iv.ogm_buff);
+       hard_iface->bat_iv.ogm_buff = NULL;
++
++      mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
+ }
+ static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
+ {
+       struct batadv_ogm_packet *batadv_ogm_packet;
+-      unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
++      void *ogm_buff;
+-      batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
++      mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
++
++      ogm_buff = hard_iface->bat_iv.ogm_buff;
++      if (!ogm_buff)
++              goto unlock;
++
++      batadv_ogm_packet = ogm_buff;
+       ether_addr_copy(batadv_ogm_packet->orig,
+                       hard_iface->net_dev->dev_addr);
+       ether_addr_copy(batadv_ogm_packet->prev_sender,
+                       hard_iface->net_dev->dev_addr);
++
++unlock:
++      mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
+ }
+ static void
+ batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
+ {
+       struct batadv_ogm_packet *batadv_ogm_packet;
+-      unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
++      void *ogm_buff;
+-      batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
++      mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
++
++      ogm_buff = hard_iface->bat_iv.ogm_buff;
++      if (!ogm_buff)
++              goto unlock;
++
++      batadv_ogm_packet = ogm_buff;
+       batadv_ogm_packet->ttl = BATADV_TTL;
++
++unlock:
++      mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
+ }
+ /* when do we schedule our own ogm to be sent */
+@@ -742,7 +772,11 @@ batadv_iv_ogm_slide_own_bcast_window(str
+       }
+ }
+-static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
++/**
++ * batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer
++ * @hard_iface: interface whose ogm buffer should be transmitted
++ */
++static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
+ {
+       struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+       unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
+@@ -753,9 +787,7 @@ static void batadv_iv_ogm_schedule(struc
+       u16 tvlv_len = 0;
+       unsigned long send_time;
+-      if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
+-          hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
+-              return;
++      lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex);
+       /* the interface gets activated here to avoid race conditions between
+        * the moment of activating the interface in
+@@ -823,6 +855,17 @@ out:
+               batadv_hardif_put(primary_if);
+ }
++static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
++{
++      if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
++          hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
++              return;
++
++      mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
++      batadv_iv_ogm_schedule_buff(hard_iface);
++      mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
++}
++
+ /**
+  * batadv_iv_orig_ifinfo_sum() - Get bcast_own sum for originator over iterface
+  * @orig_node: originator which reproadcasted the OGMs directly
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -18,6 +18,7 @@
+ #include <linux/kref.h>
+ #include <linux/limits.h>
+ #include <linux/list.h>
++#include <linux/mutex.h>
+ #include <linux/netdevice.h>
+ #include <linux/printk.h>
+ #include <linux/rculist.h>
+@@ -929,6 +930,7 @@ batadv_hardif_add_interface(struct net_d
+       INIT_LIST_HEAD(&hard_iface->list);
+       INIT_HLIST_HEAD(&hard_iface->neigh_list);
++      mutex_init(&hard_iface->bat_iv.ogm_buff_mutex);
+       spin_lock_init(&hard_iface->neigh_list_lock);
+       kref_init(&hard_iface->refcount);
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -81,6 +81,9 @@ struct batadv_hard_iface_bat_iv {
+       /** @ogm_seqno: OGM sequence number - used to identify each OGM */
+       atomic_t ogm_seqno;
++
++      /** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */
++      struct mutex ogm_buff_mutex;
+ };
+ /**
diff --git a/queue-5.3/blackhole_netdev-fix-syzkaller-reported-issue.patch b/queue-5.3/blackhole_netdev-fix-syzkaller-reported-issue.patch
new file mode 100644 (file)
index 0000000..ae9ce9d
--- /dev/null
@@ -0,0 +1,113 @@
+From b0818f80c8c1bc215bba276bd61c216014fab23b Mon Sep 17 00:00:00 2001
+From: Mahesh Bandewar <maheshb@google.com>
+Date: Fri, 11 Oct 2019 18:14:55 -0700
+Subject: blackhole_netdev: fix syzkaller reported issue
+
+From: Mahesh Bandewar <maheshb@google.com>
+
+commit b0818f80c8c1bc215bba276bd61c216014fab23b upstream.
+
+While invalidating the dst, we assign backhole_netdev instead of
+loopback device. However, this device does not have idev pointer
+and hence no ip6_ptr even if IPv6 is enabled. Possibly this has
+triggered the syzbot reported crash.
+
+The syzbot report does not have reproducer, however, this is the
+only device that doesn't have matching idev created.
+
+Crash instruction is :
+
+static inline bool ip6_ignore_linkdown(const struct net_device *dev)
+{
+        const struct inet6_dev *idev = __in6_dev_get(dev);
+
+        return !!idev->cnf.ignore_routes_with_linkdown; <= crash
+}
+
+Also ipv6 always assumes presence of idev and never checks for it
+being NULL (as does the above referenced code). So adding a idev
+for the blackhole_netdev to avoid this class of crashes in the future.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv6/addrconf.c |    7 ++++++-
+ net/ipv6/route.c    |   15 ++++++---------
+ 2 files changed, 12 insertions(+), 10 deletions(-)
+
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -6996,7 +6996,7 @@ static struct rtnl_af_ops inet6_ops __re
+ int __init addrconf_init(void)
+ {
+-      struct inet6_dev *idev;
++      struct inet6_dev *idev, *bdev;
+       int i, err;
+       err = ipv6_addr_label_init();
+@@ -7036,10 +7036,14 @@ int __init addrconf_init(void)
+        */
+       rtnl_lock();
+       idev = ipv6_add_dev(init_net.loopback_dev);
++      bdev = ipv6_add_dev(blackhole_netdev);
+       rtnl_unlock();
+       if (IS_ERR(idev)) {
+               err = PTR_ERR(idev);
+               goto errlo;
++      } else if (IS_ERR(bdev)) {
++              err = PTR_ERR(bdev);
++              goto errlo;
+       }
+       ip6_route_init_special_entries();
+@@ -7124,6 +7128,7 @@ void addrconf_cleanup(void)
+               addrconf_ifdown(dev, 1);
+       }
+       addrconf_ifdown(init_net.loopback_dev, 2);
++      addrconf_ifdown(blackhole_netdev, 2);
+       /*
+        *      Check hash table.
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -155,10 +155,9 @@ void rt6_uncached_list_del(struct rt6_in
+ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev)
+ {
+-      struct net_device *loopback_dev = net->loopback_dev;
+       int cpu;
+-      if (dev == loopback_dev)
++      if (dev == net->loopback_dev)
+               return;
+       for_each_possible_cpu(cpu) {
+@@ -171,7 +170,7 @@ static void rt6_uncached_list_flush_dev(
+                       struct net_device *rt_dev = rt->dst.dev;
+                       if (rt_idev->dev == dev) {
+-                              rt->rt6i_idev = in6_dev_get(loopback_dev);
++                              rt->rt6i_idev = in6_dev_get(blackhole_netdev);
+                               in6_dev_put(rt_idev);
+                       }
+@@ -386,13 +385,11 @@ static void ip6_dst_ifdown(struct dst_en
+ {
+       struct rt6_info *rt = (struct rt6_info *)dst;
+       struct inet6_dev *idev = rt->rt6i_idev;
+-      struct net_device *loopback_dev =
+-              dev_net(dev)->loopback_dev;
+-      if (idev && idev->dev != loopback_dev) {
+-              struct inet6_dev *loopback_idev = in6_dev_get(loopback_dev);
+-              if (loopback_idev) {
+-                      rt->rt6i_idev = loopback_idev;
++      if (idev && idev->dev != dev_net(dev)->loopback_dev) {
++              struct inet6_dev *ibdev = in6_dev_get(blackhole_netdev);
++              if (ibdev) {
++                      rt->rt6i_idev = ibdev;
+                       in6_dev_put(idev);
+               }
+       }
diff --git a/queue-5.3/bonding-fix-potential-null-deref-in-bond_update_slave_arr.patch b/queue-5.3/bonding-fix-potential-null-deref-in-bond_update_slave_arr.patch
new file mode 100644 (file)
index 0000000..1be2c39
--- /dev/null
@@ -0,0 +1,75 @@
+From a7137534b597b7c303203e6bc3ed87e87a273bb8 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Mon, 7 Oct 2019 15:43:01 -0700
+Subject: bonding: fix potential NULL deref in bond_update_slave_arr
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit a7137534b597b7c303203e6bc3ed87e87a273bb8 upstream.
+
+syzbot got a NULL dereference in bond_update_slave_arr() [1],
+happening after a failure to allocate bond->slave_arr
+
+A workqueue (bond_slave_arr_handler) is supposed to retry
+the allocation later, but if the slave is removed before
+the workqueue had a chance to complete, bond->slave_arr
+can still be NULL.
+
+[1]
+
+Failed to build slave-array.
+kasan: CONFIG_KASAN_INLINE enabled
+kasan: GPF could be caused by NULL-ptr deref or user memory access
+general protection fault: 0000 [#1] SMP KASAN PTI
+Modules linked in:
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+RIP: 0010:bond_update_slave_arr.cold+0xc6/0x198 drivers/net/bonding/bond_main.c:4039
+RSP: 0018:ffff88018fe33678 EFLAGS: 00010246
+RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffc9000290b000
+RDX: 0000000000000000 RSI: ffffffff82b63037 RDI: ffff88019745ea20
+RBP: ffff88018fe33760 R08: ffff880170754280 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
+R13: ffff88019745ea00 R14: 0000000000000000 R15: ffff88018fe338b0
+FS:  00007febd837d700(0000) GS:ffff8801dad00000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00000000004540a0 CR3: 00000001c242e005 CR4: 00000000001626f0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ [<ffffffff82b5b45e>] __bond_release_one+0x43e/0x500 drivers/net/bonding/bond_main.c:1923
+ [<ffffffff82b5b966>] bond_release drivers/net/bonding/bond_main.c:2039 [inline]
+ [<ffffffff82b5b966>] bond_do_ioctl+0x416/0x870 drivers/net/bonding/bond_main.c:3562
+ [<ffffffff83ae25f4>] dev_ifsioc+0x6f4/0x940 net/core/dev_ioctl.c:328
+ [<ffffffff83ae2e58>] dev_ioctl+0x1b8/0xc70 net/core/dev_ioctl.c:495
+ [<ffffffff83995ffd>] sock_do_ioctl+0x1bd/0x300 net/socket.c:1088
+ [<ffffffff83996a80>] sock_ioctl+0x300/0x5d0 net/socket.c:1196
+ [<ffffffff81b124db>] vfs_ioctl fs/ioctl.c:47 [inline]
+ [<ffffffff81b124db>] file_ioctl fs/ioctl.c:501 [inline]
+ [<ffffffff81b124db>] do_vfs_ioctl+0xacb/0x1300 fs/ioctl.c:688
+ [<ffffffff81b12dc6>] SYSC_ioctl fs/ioctl.c:705 [inline]
+ [<ffffffff81b12dc6>] SyS_ioctl+0xb6/0xe0 fs/ioctl.c:696
+ [<ffffffff8101ccc8>] do_syscall_64+0x528/0x770 arch/x86/entry/common.c:305
+ [<ffffffff84400091>] entry_SYSCALL_64_after_hwframe+0x42/0xb7
+
+Fixes: ee6377147409 ("bonding: Simplify the xmit function for modes that use xmit_hash")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Cc: Mahesh Bandewar <maheshb@google.com>
+Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/bonding/bond_main.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -4039,7 +4039,7 @@ out:
+                * this to-be-skipped slave to send a packet out.
+                */
+               old_arr = rtnl_dereference(bond->slave_arr);
+-              for (idx = 0; idx < old_arr->count; idx++) {
++              for (idx = 0; old_arr != NULL && idx < old_arr->count; idx++) {
+                       if (skipslave == old_arr->arr[idx]) {
+                               old_arr->arr[idx] =
+                                   old_arr->arr[old_arr->count-1];
diff --git a/queue-5.3/llc-fix-sk_buff-leak-in-llc_conn_service.patch b/queue-5.3/llc-fix-sk_buff-leak-in-llc_conn_service.patch
new file mode 100644 (file)
index 0000000..7e66f9d
--- /dev/null
@@ -0,0 +1,187 @@
+From b74555de21acd791f12c4a1aeaf653dd7ac21133 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Sun, 6 Oct 2019 14:24:25 -0700
+Subject: llc: fix sk_buff leak in llc_conn_service()
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit b74555de21acd791f12c4a1aeaf653dd7ac21133 upstream.
+
+syzbot reported:
+
+    BUG: memory leak
+    unreferenced object 0xffff88811eb3de00 (size 224):
+       comm "syz-executor559", pid 7315, jiffies 4294943019 (age 10.300s)
+       hex dump (first 32 bytes):
+         00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+         00 a0 38 24 81 88 ff ff 00 c0 f2 15 81 88 ff ff  ..8$............
+       backtrace:
+         [<000000008d1c66a1>] kmemleak_alloc_recursive  include/linux/kmemleak.h:55 [inline]
+         [<000000008d1c66a1>] slab_post_alloc_hook mm/slab.h:439 [inline]
+         [<000000008d1c66a1>] slab_alloc_node mm/slab.c:3269 [inline]
+         [<000000008d1c66a1>] kmem_cache_alloc_node+0x153/0x2a0 mm/slab.c:3579
+         [<00000000447d9496>] __alloc_skb+0x6e/0x210 net/core/skbuff.c:198
+         [<000000000cdbf82f>] alloc_skb include/linux/skbuff.h:1058 [inline]
+         [<000000000cdbf82f>] llc_alloc_frame+0x66/0x110 net/llc/llc_sap.c:54
+         [<000000002418b52e>] llc_conn_ac_send_sabme_cmd_p_set_x+0x2f/0x140  net/llc/llc_c_ac.c:777
+         [<000000001372ae17>] llc_exec_conn_trans_actions net/llc/llc_conn.c:475  [inline]
+         [<000000001372ae17>] llc_conn_service net/llc/llc_conn.c:400 [inline]
+         [<000000001372ae17>] llc_conn_state_process+0x1ac/0x640  net/llc/llc_conn.c:75
+         [<00000000f27e53c1>] llc_establish_connection+0x110/0x170  net/llc/llc_if.c:109
+         [<00000000291b2ca0>] llc_ui_connect+0x10e/0x370 net/llc/af_llc.c:477
+         [<000000000f9c740b>] __sys_connect+0x11d/0x170 net/socket.c:1840
+         [...]
+
+The bug is that most callers of llc_conn_send_pdu() assume it consumes a
+reference to the skb, when actually due to commit b85ab56c3f81 ("llc:
+properly handle dev_queue_xmit() return value") it doesn't.
+
+Revert most of that commit, and instead make the few places that need
+llc_conn_send_pdu() to *not* consume a reference call skb_get() before.
+
+Fixes: b85ab56c3f81 ("llc: properly handle dev_queue_xmit() return value")
+Reported-by: syzbot+6b825a6494a04cc0e3f7@syzkaller.appspotmail.com
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/llc_conn.h |    2 +-
+ net/llc/llc_c_ac.c     |    8 ++++++--
+ net/llc/llc_conn.c     |   32 +++++++++-----------------------
+ 3 files changed, 16 insertions(+), 26 deletions(-)
+
+--- a/include/net/llc_conn.h
++++ b/include/net/llc_conn.h
+@@ -104,7 +104,7 @@ void llc_sk_reset(struct sock *sk);
+ /* Access to a connection */
+ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb);
+-int llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
++void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
+ void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb);
+ void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit);
+ void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit);
+--- a/net/llc/llc_c_ac.c
++++ b/net/llc/llc_c_ac.c
+@@ -372,6 +372,7 @@ int llc_conn_ac_send_i_cmd_p_set_1(struc
+       llc_pdu_init_as_i_cmd(skb, 1, llc->vS, llc->vR);
+       rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+       if (likely(!rc)) {
++              skb_get(skb);
+               llc_conn_send_pdu(sk, skb);
+               llc_conn_ac_inc_vs_by_1(sk, skb);
+       }
+@@ -389,7 +390,8 @@ static int llc_conn_ac_send_i_cmd_p_set_
+       llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
+       rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+       if (likely(!rc)) {
+-              rc = llc_conn_send_pdu(sk, skb);
++              skb_get(skb);
++              llc_conn_send_pdu(sk, skb);
+               llc_conn_ac_inc_vs_by_1(sk, skb);
+       }
+       return rc;
+@@ -406,6 +408,7 @@ int llc_conn_ac_send_i_xxx_x_set_0(struc
+       llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
+       rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+       if (likely(!rc)) {
++              skb_get(skb);
+               llc_conn_send_pdu(sk, skb);
+               llc_conn_ac_inc_vs_by_1(sk, skb);
+       }
+@@ -916,7 +919,8 @@ static int llc_conn_ac_send_i_rsp_f_set_
+       llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR);
+       rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+       if (likely(!rc)) {
+-              rc = llc_conn_send_pdu(sk, skb);
++              skb_get(skb);
++              llc_conn_send_pdu(sk, skb);
+               llc_conn_ac_inc_vs_by_1(sk, skb);
+       }
+       return rc;
+--- a/net/llc/llc_conn.c
++++ b/net/llc/llc_conn.c
+@@ -30,7 +30,7 @@
+ #endif
+ static int llc_find_offset(int state, int ev_type);
+-static int llc_conn_send_pdus(struct sock *sk, struct sk_buff *skb);
++static void llc_conn_send_pdus(struct sock *sk);
+ static int llc_conn_service(struct sock *sk, struct sk_buff *skb);
+ static int llc_exec_conn_trans_actions(struct sock *sk,
+                                      struct llc_conn_state_trans *trans,
+@@ -193,11 +193,11 @@ out_skb_put:
+       return rc;
+ }
+-int llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb)
++void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb)
+ {
+       /* queue PDU to send to MAC layer */
+       skb_queue_tail(&sk->sk_write_queue, skb);
+-      return llc_conn_send_pdus(sk, skb);
++      llc_conn_send_pdus(sk);
+ }
+ /**
+@@ -255,7 +255,7 @@ void llc_conn_resend_i_pdu_as_cmd(struct
+       if (howmany_resend > 0)
+               llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO;
+       /* any PDUs to re-send are queued up; start sending to MAC */
+-      llc_conn_send_pdus(sk, NULL);
++      llc_conn_send_pdus(sk);
+ out:;
+ }
+@@ -296,7 +296,7 @@ void llc_conn_resend_i_pdu_as_rsp(struct
+       if (howmany_resend > 0)
+               llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO;
+       /* any PDUs to re-send are queued up; start sending to MAC */
+-      llc_conn_send_pdus(sk, NULL);
++      llc_conn_send_pdus(sk);
+ out:;
+ }
+@@ -340,16 +340,12 @@ out:
+ /**
+  *    llc_conn_send_pdus - Sends queued PDUs
+  *    @sk: active connection
+- *    @hold_skb: the skb held by caller, or NULL if does not care
+  *
+- *    Sends queued pdus to MAC layer for transmission. When @hold_skb is
+- *    NULL, always return 0. Otherwise, return 0 if @hold_skb is sent
+- *    successfully, or 1 for failure.
++ *    Sends queued pdus to MAC layer for transmission.
+  */
+-static int llc_conn_send_pdus(struct sock *sk, struct sk_buff *hold_skb)
++static void llc_conn_send_pdus(struct sock *sk)
+ {
+       struct sk_buff *skb;
+-      int ret = 0;
+       while ((skb = skb_dequeue(&sk->sk_write_queue)) != NULL) {
+               struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+@@ -361,20 +357,10 @@ static int llc_conn_send_pdus(struct soc
+                       skb_queue_tail(&llc_sk(sk)->pdu_unack_q, skb);
+                       if (!skb2)
+                               break;
+-                      dev_queue_xmit(skb2);
+-              } else {
+-                      bool is_target = skb == hold_skb;
+-                      int rc;
+-
+-                      if (is_target)
+-                              skb_get(skb);
+-                      rc = dev_queue_xmit(skb);
+-                      if (is_target)
+-                              ret = rc;
++                      skb = skb2;
+               }
++              dev_queue_xmit(skb);
+       }
+-
+-      return ret;
+ }
+ /**
diff --git a/queue-5.3/llc-fix-sk_buff-leak-in-llc_sap_state_process.patch b/queue-5.3/llc-fix-sk_buff-leak-in-llc_sap_state_process.patch
new file mode 100644 (file)
index 0000000..04a1615
--- /dev/null
@@ -0,0 +1,131 @@
+From c6ee11c39fcc1fb55130748990a8f199e76263b4 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Sun, 6 Oct 2019 14:24:24 -0700
+Subject: llc: fix sk_buff leak in llc_sap_state_process()
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit c6ee11c39fcc1fb55130748990a8f199e76263b4 upstream.
+
+syzbot reported:
+
+    BUG: memory leak
+    unreferenced object 0xffff888116270800 (size 224):
+       comm "syz-executor641", pid 7047, jiffies 4294947360 (age 13.860s)
+       hex dump (first 32 bytes):
+         00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+         00 20 e1 2a 81 88 ff ff 00 40 3d 2a 81 88 ff ff  . .*.....@=*....
+       backtrace:
+         [<000000004d41b4cc>] kmemleak_alloc_recursive  include/linux/kmemleak.h:55 [inline]
+         [<000000004d41b4cc>] slab_post_alloc_hook mm/slab.h:439 [inline]
+         [<000000004d41b4cc>] slab_alloc_node mm/slab.c:3269 [inline]
+         [<000000004d41b4cc>] kmem_cache_alloc_node+0x153/0x2a0 mm/slab.c:3579
+         [<00000000506a5965>] __alloc_skb+0x6e/0x210 net/core/skbuff.c:198
+         [<000000001ba5a161>] alloc_skb include/linux/skbuff.h:1058 [inline]
+         [<000000001ba5a161>] alloc_skb_with_frags+0x5f/0x250  net/core/skbuff.c:5327
+         [<0000000047d9c78b>] sock_alloc_send_pskb+0x269/0x2a0  net/core/sock.c:2225
+         [<000000003828fe54>] sock_alloc_send_skb+0x32/0x40 net/core/sock.c:2242
+         [<00000000e34d94f9>] llc_ui_sendmsg+0x10a/0x540 net/llc/af_llc.c:933
+         [<00000000de2de3fb>] sock_sendmsg_nosec net/socket.c:652 [inline]
+         [<00000000de2de3fb>] sock_sendmsg+0x54/0x70 net/socket.c:671
+         [<000000008fe16e7a>] __sys_sendto+0x148/0x1f0 net/socket.c:1964
+        [...]
+
+The bug is that llc_sap_state_process() always takes an extra reference
+to the skb, but sometimes neither llc_sap_next_state() nor
+llc_sap_state_process() itself drops this reference.
+
+Fix it by changing llc_sap_next_state() to never consume a reference to
+the skb, rather than sometimes do so and sometimes not.  Then remove the
+extra skb_get() and kfree_skb() from llc_sap_state_process().
+
+Reported-by: syzbot+6bf095f9becf5efef645@syzkaller.appspotmail.com
+Reported-by: syzbot+31c16aa4202dace3812e@syzkaller.appspotmail.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/llc/llc_s_ac.c |   12 +++++++++---
+ net/llc/llc_sap.c  |   23 ++++++++---------------
+ 2 files changed, 17 insertions(+), 18 deletions(-)
+
+--- a/net/llc/llc_s_ac.c
++++ b/net/llc/llc_s_ac.c
+@@ -58,8 +58,10 @@ int llc_sap_action_send_ui(struct llc_sa
+                           ev->daddr.lsap, LLC_PDU_CMD);
+       llc_pdu_init_as_ui_cmd(skb);
+       rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
+-      if (likely(!rc))
++      if (likely(!rc)) {
++              skb_get(skb);
+               rc = dev_queue_xmit(skb);
++      }
+       return rc;
+ }
+@@ -81,8 +83,10 @@ int llc_sap_action_send_xid_c(struct llc
+                           ev->daddr.lsap, LLC_PDU_CMD);
+       llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0);
+       rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
+-      if (likely(!rc))
++      if (likely(!rc)) {
++              skb_get(skb);
+               rc = dev_queue_xmit(skb);
++      }
+       return rc;
+ }
+@@ -135,8 +139,10 @@ int llc_sap_action_send_test_c(struct ll
+                           ev->daddr.lsap, LLC_PDU_CMD);
+       llc_pdu_init_as_test_cmd(skb);
+       rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
+-      if (likely(!rc))
++      if (likely(!rc)) {
++              skb_get(skb);
+               rc = dev_queue_xmit(skb);
++      }
+       return rc;
+ }
+--- a/net/llc/llc_sap.c
++++ b/net/llc/llc_sap.c
+@@ -197,29 +197,22 @@ out:
+  *    After executing actions of the event, upper layer will be indicated
+  *    if needed(on receiving an UI frame). sk can be null for the
+  *    datalink_proto case.
++ *
++ *    This function always consumes a reference to the skb.
+  */
+ static void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb)
+ {
+       struct llc_sap_state_ev *ev = llc_sap_ev(skb);
+-      /*
+-       * We have to hold the skb, because llc_sap_next_state
+-       * will kfree it in the sending path and we need to
+-       * look at the skb->cb, where we encode llc_sap_state_ev.
+-       */
+-      skb_get(skb);
+       ev->ind_cfm_flag = 0;
+       llc_sap_next_state(sap, skb);
+-      if (ev->ind_cfm_flag == LLC_IND) {
+-              if (skb->sk->sk_state == TCP_LISTEN)
+-                      kfree_skb(skb);
+-              else {
+-                      llc_save_primitive(skb->sk, skb, ev->prim);
+-                      /* queue skb to the user. */
+-                      if (sock_queue_rcv_skb(skb->sk, skb))
+-                              kfree_skb(skb);
+-              }
++      if (ev->ind_cfm_flag == LLC_IND && skb->sk->sk_state != TCP_LISTEN) {
++              llc_save_primitive(skb->sk, skb, ev->prim);
++
++              /* queue skb to the user. */
++              if (sock_queue_rcv_skb(skb->sk, skb) == 0)
++                      return;
+       }
+       kfree_skb(skb);
+ }
diff --git a/queue-5.3/net-sched-sch_sfb-don-t-call-qdisc_put-while-holding-tree-lock.patch b/queue-5.3/net-sched-sch_sfb-don-t-call-qdisc_put-while-holding-tree-lock.patch
new file mode 100644 (file)
index 0000000..c53a73f
--- /dev/null
@@ -0,0 +1,113 @@
+From e3ae1f96accd21405715fe9c56b4d83bc7d96d44 Mon Sep 17 00:00:00 2001
+From: Vlad Buslov <vladbu@mellanox.com>
+Date: Tue, 24 Sep 2019 18:51:18 +0300
+Subject: net: sched: sch_sfb: don't call qdisc_put() while holding tree lock
+
+From: Vlad Buslov <vladbu@mellanox.com>
+
+commit e3ae1f96accd21405715fe9c56b4d83bc7d96d44 upstream.
+
+Recent changes that removed rtnl dependency from rules update path of tc
+also made tcf_block_put() function sleeping. This function is called from
+ops->destroy() of several Qdisc implementations, which in turn is called by
+qdisc_put(). Some Qdiscs call qdisc_put() while holding sch tree spinlock,
+which results sleeping-while-atomic BUG.
+
+Steps to reproduce for sfb:
+
+tc qdisc add dev ens1f0 handle 1: root sfb
+tc qdisc add dev ens1f0 parent 1:10 handle 50: sfq perturb 10
+tc qdisc change dev ens1f0 root handle 1: sfb
+
+Resulting dmesg:
+
+[ 7265.938717] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:909
+[ 7265.940152] in_atomic(): 1, irqs_disabled(): 0, pid: 28579, name: tc
+[ 7265.941455] INFO: lockdep is turned off.
+[ 7265.942744] CPU: 11 PID: 28579 Comm: tc Tainted: G        W         5.3.0-rc8+ #721
+[ 7265.944065] Hardware name: Supermicro SYS-2028TP-DECR/X10DRT-P, BIOS 2.0b 03/30/2017
+[ 7265.945396] Call Trace:
+[ 7265.946709]  dump_stack+0x85/0xc0
+[ 7265.947994]  ___might_sleep.cold+0xac/0xbc
+[ 7265.949282]  __mutex_lock+0x5b/0x960
+[ 7265.950543]  ? tcf_chain0_head_change_cb_del.isra.0+0x1b/0xf0
+[ 7265.951803]  ? tcf_chain0_head_change_cb_del.isra.0+0x1b/0xf0
+[ 7265.953022]  tcf_chain0_head_change_cb_del.isra.0+0x1b/0xf0
+[ 7265.954248]  tcf_block_put_ext.part.0+0x21/0x50
+[ 7265.955478]  tcf_block_put+0x50/0x70
+[ 7265.956694]  sfq_destroy+0x15/0x50 [sch_sfq]
+[ 7265.957898]  qdisc_destroy+0x5f/0x160
+[ 7265.959099]  sfb_change+0x175/0x330 [sch_sfb]
+[ 7265.960304]  tc_modify_qdisc+0x324/0x840
+[ 7265.961503]  rtnetlink_rcv_msg+0x170/0x4b0
+[ 7265.962692]  ? netlink_deliver_tap+0x95/0x400
+[ 7265.963876]  ? rtnl_dellink+0x2d0/0x2d0
+[ 7265.965064]  netlink_rcv_skb+0x49/0x110
+[ 7265.966251]  netlink_unicast+0x171/0x200
+[ 7265.967427]  netlink_sendmsg+0x224/0x3f0
+[ 7265.968595]  sock_sendmsg+0x5e/0x60
+[ 7265.969753]  ___sys_sendmsg+0x2ae/0x330
+[ 7265.970916]  ? ___sys_recvmsg+0x159/0x1f0
+[ 7265.972074]  ? do_wp_page+0x9c/0x790
+[ 7265.973233]  ? __handle_mm_fault+0xcd3/0x19e0
+[ 7265.974407]  __sys_sendmsg+0x59/0xa0
+[ 7265.975591]  do_syscall_64+0x5c/0xb0
+[ 7265.976753]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
+[ 7265.977938] RIP: 0033:0x7f229069f7b8
+[ 7265.979117] Code: 89 02 48 c7 c0 ff ff ff ff eb bb 0f 1f 80 00 00 00 00 f3 0f 1e fa 48 8d 05 65 8f 0c 00 8b 00 85 c0 75 17 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 48 83 ec 28 89 5
+4
+[ 7265.981681] RSP: 002b:00007ffd7ed2d158 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+[ 7265.983001] RAX: ffffffffffffffda RBX: 000000005d813ca1 RCX: 00007f229069f7b8
+[ 7265.984336] RDX: 0000000000000000 RSI: 00007ffd7ed2d1c0 RDI: 0000000000000003
+[ 7265.985682] RBP: 0000000000000000 R08: 0000000000000001 R09: 000000000165c9a0
+[ 7265.987021] R10: 0000000000404eda R11: 0000000000000246 R12: 0000000000000001
+[ 7265.988309] R13: 000000000047f640 R14: 0000000000000000 R15: 0000000000000000
+
+In sfb_change() function use qdisc_purge_queue() instead of
+qdisc_tree_flush_backlog() to properly reset old child Qdisc and save
+pointer to it into local temporary variable. Put reference to Qdisc after
+sch tree lock is released in order not to call potentially sleeping cls API
+in atomic section. This is safe to do because Qdisc has already been reset
+by qdisc_purge_queue() inside sch tree lock critical section.
+
+Reported-by: syzbot+ac54455281db908c581e@syzkaller.appspotmail.com
+Fixes: c266f64dbfa2 ("net: sched: protect block state with mutex")
+Suggested-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sched/sch_sfb.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/net/sched/sch_sfb.c
++++ b/net/sched/sch_sfb.c
+@@ -488,7 +488,7 @@ static int sfb_change(struct Qdisc *sch,
+                     struct netlink_ext_ack *extack)
+ {
+       struct sfb_sched_data *q = qdisc_priv(sch);
+-      struct Qdisc *child;
++      struct Qdisc *child, *old;
+       struct nlattr *tb[TCA_SFB_MAX + 1];
+       const struct tc_sfb_qopt *ctl = &sfb_default_ops;
+       u32 limit;
+@@ -518,8 +518,8 @@ static int sfb_change(struct Qdisc *sch,
+               qdisc_hash_add(child, true);
+       sch_tree_lock(sch);
+-      qdisc_tree_flush_backlog(q->qdisc);
+-      qdisc_put(q->qdisc);
++      qdisc_purge_queue(q->qdisc);
++      old = q->qdisc;
+       q->qdisc = child;
+       q->rehash_interval = msecs_to_jiffies(ctl->rehash_interval);
+@@ -542,6 +542,7 @@ static int sfb_change(struct Qdisc *sch,
+       sfb_init_perturbation(1, q);
+       sch_tree_unlock(sch);
++      qdisc_put(old);
+       return 0;
+ }
diff --git a/queue-5.3/net-usb-sr9800-fix-uninitialized-local-variable.patch b/queue-5.3/net-usb-sr9800-fix-uninitialized-local-variable.patch
new file mode 100644 (file)
index 0000000..db7e78b
--- /dev/null
@@ -0,0 +1,32 @@
+From 77b6d09f4ae66d42cd63b121af67780ae3d1a5e9 Mon Sep 17 00:00:00 2001
+From: Valentin Vidic <vvidic@valentin-vidic.from.hr>
+Date: Tue, 15 Oct 2019 22:20:20 +0200
+Subject: net: usb: sr9800: fix uninitialized local variable
+
+From: Valentin Vidic <vvidic@valentin-vidic.from.hr>
+
+commit 77b6d09f4ae66d42cd63b121af67780ae3d1a5e9 upstream.
+
+Make sure res does not contain random value if the call to
+sr_read_cmd fails for some reason.
+
+Reported-by: syzbot+f1842130bbcfb335bac1@syzkaller.appspotmail.com
+Signed-off-by: Valentin Vidic <vvidic@valentin-vidic.from.hr>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/usb/sr9800.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/usb/sr9800.c
++++ b/drivers/net/usb/sr9800.c
+@@ -336,7 +336,7 @@ static void sr_set_multicast(struct net_
+ static int sr_mdio_read(struct net_device *net, int phy_id, int loc)
+ {
+       struct usbnet *dev = netdev_priv(net);
+-      __le16 res;
++      __le16 res = 0;
+       mutex_lock(&dev->phy_mutex);
+       sr_set_sw_mii(dev);
diff --git a/queue-5.3/netfilter-conntrack-avoid-possible-false-sharing.patch b/queue-5.3/netfilter-conntrack-avoid-possible-false-sharing.patch
new file mode 100644 (file)
index 0000000..4fe64f4
--- /dev/null
@@ -0,0 +1,91 @@
+From e37542ba111f3974dc622ae0a21c1787318de500 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 9 Oct 2019 09:19:13 -0700
+Subject: netfilter: conntrack: avoid possible false sharing
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit e37542ba111f3974dc622ae0a21c1787318de500 upstream.
+
+As hinted by KCSAN, we need at least one READ_ONCE()
+to prevent a compiler optimization.
+
+More details on :
+https://github.com/google/ktsan/wiki/READ_ONCE-and-WRITE_ONCE#it-may-improve-performance
+
+sysbot report :
+BUG: KCSAN: data-race in __nf_ct_refresh_acct / __nf_ct_refresh_acct
+
+read to 0xffff888123eb4f08 of 4 bytes by interrupt on cpu 0:
+ __nf_ct_refresh_acct+0xd4/0x1b0 net/netfilter/nf_conntrack_core.c:1796
+ nf_ct_refresh_acct include/net/netfilter/nf_conntrack.h:201 [inline]
+ nf_conntrack_tcp_packet+0xd40/0x3390 net/netfilter/nf_conntrack_proto_tcp.c:1161
+ nf_conntrack_handle_packet net/netfilter/nf_conntrack_core.c:1633 [inline]
+ nf_conntrack_in+0x410/0xaa0 net/netfilter/nf_conntrack_core.c:1727
+ ipv4_conntrack_in+0x27/0x40 net/netfilter/nf_conntrack_proto.c:178
+ nf_hook_entry_hookfn include/linux/netfilter.h:135 [inline]
+ nf_hook_slow+0x83/0x160 net/netfilter/core.c:512
+ nf_hook include/linux/netfilter.h:260 [inline]
+ NF_HOOK include/linux/netfilter.h:303 [inline]
+ ip_rcv+0x12f/0x1a0 net/ipv4/ip_input.c:523
+ __netif_receive_skb_one_core+0xa7/0xe0 net/core/dev.c:5004
+ __netif_receive_skb+0x37/0xf0 net/core/dev.c:5118
+ netif_receive_skb_internal+0x59/0x190 net/core/dev.c:5208
+ napi_skb_finish net/core/dev.c:5671 [inline]
+ napi_gro_receive+0x28f/0x330 net/core/dev.c:5704
+ receive_buf+0x284/0x30b0 drivers/net/virtio_net.c:1061
+ virtnet_receive drivers/net/virtio_net.c:1323 [inline]
+ virtnet_poll+0x436/0x7d0 drivers/net/virtio_net.c:1428
+ napi_poll net/core/dev.c:6352 [inline]
+ net_rx_action+0x3ae/0xa50 net/core/dev.c:6418
+ __do_softirq+0x115/0x33f kernel/softirq.c:292
+
+write to 0xffff888123eb4f08 of 4 bytes by task 7191 on cpu 1:
+ __nf_ct_refresh_acct+0xfb/0x1b0 net/netfilter/nf_conntrack_core.c:1797
+ nf_ct_refresh_acct include/net/netfilter/nf_conntrack.h:201 [inline]
+ nf_conntrack_tcp_packet+0xd40/0x3390 net/netfilter/nf_conntrack_proto_tcp.c:1161
+ nf_conntrack_handle_packet net/netfilter/nf_conntrack_core.c:1633 [inline]
+ nf_conntrack_in+0x410/0xaa0 net/netfilter/nf_conntrack_core.c:1727
+ ipv4_conntrack_local+0xbe/0x130 net/netfilter/nf_conntrack_proto.c:200
+ nf_hook_entry_hookfn include/linux/netfilter.h:135 [inline]
+ nf_hook_slow+0x83/0x160 net/netfilter/core.c:512
+ nf_hook include/linux/netfilter.h:260 [inline]
+ __ip_local_out+0x1f7/0x2b0 net/ipv4/ip_output.c:114
+ ip_local_out+0x31/0x90 net/ipv4/ip_output.c:123
+ __ip_queue_xmit+0x3a8/0xa40 net/ipv4/ip_output.c:532
+ ip_queue_xmit+0x45/0x60 include/net/ip.h:236
+ __tcp_transmit_skb+0xdeb/0x1cd0 net/ipv4/tcp_output.c:1158
+ __tcp_send_ack+0x246/0x300 net/ipv4/tcp_output.c:3685
+ tcp_send_ack+0x34/0x40 net/ipv4/tcp_output.c:3691
+ tcp_cleanup_rbuf+0x130/0x360 net/ipv4/tcp.c:1575
+
+Reported by Kernel Concurrency Sanitizer on:
+CPU: 1 PID: 7191 Comm: syz-fuzzer Not tainted 5.3.0+ #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+
+Fixes: cc16921351d8 ("netfilter: conntrack: avoid same-timeout update")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Cc: Jozsef Kadlecsik <kadlec@netfilter.org>
+Cc: Florian Westphal <fw@strlen.de>
+Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/nf_conntrack_core.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -1793,8 +1793,8 @@ void __nf_ct_refresh_acct(struct nf_conn
+       if (nf_ct_is_confirmed(ct))
+               extra_jiffies += nfct_time_stamp;
+-      if (ct->timeout != extra_jiffies)
+-              ct->timeout = extra_jiffies;
++      if (READ_ONCE(ct->timeout) != extra_jiffies)
++              WRITE_ONCE(ct->timeout, extra_jiffies);
+ acct:
+       if (do_acct)
+               nf_ct_acct_update(ct, ctinfo, skb->len);
diff --git a/queue-5.3/nfc-pn533-fix-use-after-free-and-memleaks.patch b/queue-5.3/nfc-pn533-fix-use-after-free-and-memleaks.patch
new file mode 100644 (file)
index 0000000..dbec1e3
--- /dev/null
@@ -0,0 +1,51 @@
+From 6af3aa57a0984e061f61308fe181a9a12359fecc Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 7 Oct 2019 18:40:59 +0200
+Subject: NFC: pn533: fix use-after-free and memleaks
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 6af3aa57a0984e061f61308fe181a9a12359fecc upstream.
+
+The driver would fail to deregister and its class device and free
+related resources on late probe errors.
+
+Reported-by: syzbot+cb035c75c03dbe34b796@syzkaller.appspotmail.com
+Fixes: 32ecc75ded72 ("NFC: pn533: change order operations in dev registation")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/nfc/pn533/usb.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/nfc/pn533/usb.c
++++ b/drivers/nfc/pn533/usb.c
+@@ -547,18 +547,25 @@ static int pn533_usb_probe(struct usb_in
+       rc = pn533_finalize_setup(priv);
+       if (rc)
+-              goto error;
++              goto err_deregister;
+       usb_set_intfdata(interface, phy);
+       return 0;
++err_deregister:
++      pn533_unregister_device(phy->priv);
+ error:
++      usb_kill_urb(phy->in_urb);
++      usb_kill_urb(phy->out_urb);
++      usb_kill_urb(phy->ack_urb);
++
+       usb_free_urb(phy->in_urb);
+       usb_free_urb(phy->out_urb);
+       usb_free_urb(phy->ack_urb);
+       usb_put_dev(phy->udev);
+       kfree(in_buf);
++      kfree(phy->ack_buffer);
+       return rc;
+ }
diff --git a/queue-5.3/rxrpc-fix-call-ref-leak.patch b/queue-5.3/rxrpc-fix-call-ref-leak.patch
new file mode 100644 (file)
index 0000000..b813350
--- /dev/null
@@ -0,0 +1,47 @@
+From c48fc11b69e95007109206311b0187a3090591f3 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Mon, 7 Oct 2019 10:58:28 +0100
+Subject: rxrpc: Fix call ref leak
+
+From: David Howells <dhowells@redhat.com>
+
+commit c48fc11b69e95007109206311b0187a3090591f3 upstream.
+
+When sendmsg() finds a call to continue on with, if the call is in an
+inappropriate state, it doesn't release the ref it just got on that call
+before returning an error.
+
+This causes the following symptom to show up with kasan:
+
+       BUG: KASAN: use-after-free in rxrpc_send_keepalive+0x8a2/0x940
+       net/rxrpc/output.c:635
+       Read of size 8 at addr ffff888064219698 by task kworker/0:3/11077
+
+where line 635 is:
+
+       whdr.epoch      = htonl(peer->local->rxnet->epoch);
+
+The local endpoint (which cannot be pinned by the call) has been released,
+but not the peer (which is pinned by the call).
+
+Fix this by releasing the call in the error path.
+
+Fixes: 37411cad633f ("rxrpc: Fix potential NULL-pointer exception")
+Reported-by: syzbot+d850c266e3df14da1d31@syzkaller.appspotmail.com
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/rxrpc/sendmsg.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/rxrpc/sendmsg.c
++++ b/net/rxrpc/sendmsg.c
+@@ -661,6 +661,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *
+               case RXRPC_CALL_SERVER_PREALLOC:
+               case RXRPC_CALL_SERVER_SECURING:
+               case RXRPC_CALL_SERVER_ACCEPTING:
++                      rxrpc_put_call(call, rxrpc_call_put);
+                       ret = -EBUSY;
+                       goto error_release_sock;
+               default:
diff --git a/queue-5.3/rxrpc-fix-trace-after-put-looking-at-the-put-peer-record.patch b/queue-5.3/rxrpc-fix-trace-after-put-looking-at-the-put-peer-record.patch
new file mode 100644 (file)
index 0000000..7565c54
--- /dev/null
@@ -0,0 +1,107 @@
+From 55f6c98e3674ce16038a1949c3f9ca5a9a99f289 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Mon, 7 Oct 2019 10:58:29 +0100
+Subject: rxrpc: Fix trace-after-put looking at the put peer record
+
+From: David Howells <dhowells@redhat.com>
+
+commit 55f6c98e3674ce16038a1949c3f9ca5a9a99f289 upstream.
+
+rxrpc_put_peer() calls trace_rxrpc_peer() after it has done the decrement
+of the refcount - which looks at the debug_id in the peer record.  But
+unless the refcount was reduced to zero, we no longer have the right to
+look in the record and, indeed, it may be deleted by some other thread.
+
+Fix this by getting the debug_id out before decrementing the refcount and
+then passing that into the tracepoint.
+
+This can cause the following symptoms:
+
+    BUG: KASAN: use-after-free in __rxrpc_put_peer net/rxrpc/peer_object.c:411
+    [inline]
+    BUG: KASAN: use-after-free in rxrpc_put_peer+0x685/0x6a0
+    net/rxrpc/peer_object.c:435
+    Read of size 8 at addr ffff888097ec0058 by task syz-executor823/24216
+
+Fixes: 1159d4b496f5 ("rxrpc: Add a tracepoint to track rxrpc_peer refcounting")
+Reported-by: syzbot+b9be979c55f2bea8ed30@syzkaller.appspotmail.com
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/trace/events/rxrpc.h |    6 +++---
+ net/rxrpc/peer_object.c      |   11 +++++++----
+ 2 files changed, 10 insertions(+), 7 deletions(-)
+
+--- a/include/trace/events/rxrpc.h
++++ b/include/trace/events/rxrpc.h
+@@ -519,10 +519,10 @@ TRACE_EVENT(rxrpc_local,
+           );
+ TRACE_EVENT(rxrpc_peer,
+-          TP_PROTO(struct rxrpc_peer *peer, enum rxrpc_peer_trace op,
++          TP_PROTO(unsigned int peer_debug_id, enum rxrpc_peer_trace op,
+                    int usage, const void *where),
+-          TP_ARGS(peer, op, usage, where),
++          TP_ARGS(peer_debug_id, op, usage, where),
+           TP_STRUCT__entry(
+                   __field(unsigned int,       peer            )
+@@ -532,7 +532,7 @@ TRACE_EVENT(rxrpc_peer,
+                            ),
+           TP_fast_assign(
+-                  __entry->peer = peer->debug_id;
++                  __entry->peer = peer_debug_id;
+                   __entry->op = op;
+                   __entry->usage = usage;
+                   __entry->where = where;
+--- a/net/rxrpc/peer_object.c
++++ b/net/rxrpc/peer_object.c
+@@ -381,7 +381,7 @@ struct rxrpc_peer *rxrpc_get_peer(struct
+       int n;
+       n = atomic_inc_return(&peer->usage);
+-      trace_rxrpc_peer(peer, rxrpc_peer_got, n, here);
++      trace_rxrpc_peer(peer->debug_id, rxrpc_peer_got, n, here);
+       return peer;
+ }
+@@ -395,7 +395,7 @@ struct rxrpc_peer *rxrpc_get_peer_maybe(
+       if (peer) {
+               int n = atomic_fetch_add_unless(&peer->usage, 1, 0);
+               if (n > 0)
+-                      trace_rxrpc_peer(peer, rxrpc_peer_got, n + 1, here);
++                      trace_rxrpc_peer(peer->debug_id, rxrpc_peer_got, n + 1, here);
+               else
+                       peer = NULL;
+       }
+@@ -426,11 +426,13 @@ static void __rxrpc_put_peer(struct rxrp
+ void rxrpc_put_peer(struct rxrpc_peer *peer)
+ {
+       const void *here = __builtin_return_address(0);
++      unsigned int debug_id;
+       int n;
+       if (peer) {
++              debug_id = peer->debug_id;
+               n = atomic_dec_return(&peer->usage);
+-              trace_rxrpc_peer(peer, rxrpc_peer_put, n, here);
++              trace_rxrpc_peer(debug_id, rxrpc_peer_put, n, here);
+               if (n == 0)
+                       __rxrpc_put_peer(peer);
+       }
+@@ -443,10 +445,11 @@ void rxrpc_put_peer(struct rxrpc_peer *p
+ void rxrpc_put_peer_locked(struct rxrpc_peer *peer)
+ {
+       const void *here = __builtin_return_address(0);
++      unsigned int debug_id = peer->debug_id;
+       int n;
+       n = atomic_dec_return(&peer->usage);
+-      trace_rxrpc_peer(peer, rxrpc_peer_put, n, here);
++      trace_rxrpc_peer(debug_id, rxrpc_peer_put, n, here);
+       if (n == 0) {
+               hash_del_rcu(&peer->hash_link);
+               list_del_init(&peer->keepalive_link);
diff --git a/queue-5.3/rxrpc-rxrpc_peer-needs-to-hold-a-ref-on-the-rxrpc_local-record.patch b/queue-5.3/rxrpc-rxrpc_peer-needs-to-hold-a-ref-on-the-rxrpc_local-record.patch
new file mode 100644 (file)
index 0000000..4c72aa6
--- /dev/null
@@ -0,0 +1,70 @@
+From 9ebeddef58c41bd700419cdcece24cf64ce32276 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Mon, 7 Oct 2019 10:58:29 +0100
+Subject: rxrpc: rxrpc_peer needs to hold a ref on the rxrpc_local record
+
+From: David Howells <dhowells@redhat.com>
+
+commit 9ebeddef58c41bd700419cdcece24cf64ce32276 upstream.
+
+The rxrpc_peer record needs to hold a reference on the rxrpc_local record
+it points as the peer is used as a base to access information in the
+rxrpc_local record.
+
+This can cause problems in __rxrpc_put_peer(), where we need the network
+namespace pointer, and in rxrpc_send_keepalive(), where we need to access
+the UDP socket, leading to symptoms like:
+
+    BUG: KASAN: use-after-free in __rxrpc_put_peer net/rxrpc/peer_object.c:411
+    [inline]
+    BUG: KASAN: use-after-free in rxrpc_put_peer+0x685/0x6a0
+    net/rxrpc/peer_object.c:435
+    Read of size 8 at addr ffff888097ec0058 by task syz-executor823/24216
+
+Fix this by taking a ref on the local record for the peer record.
+
+Fixes: ace45bec6d77 ("rxrpc: Fix firewall route keepalive")
+Fixes: 2baec2c3f854 ("rxrpc: Support network namespacing")
+Reported-by: syzbot+b9be979c55f2bea8ed30@syzkaller.appspotmail.com
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/rxrpc/peer_object.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/net/rxrpc/peer_object.c
++++ b/net/rxrpc/peer_object.c
+@@ -216,7 +216,7 @@ struct rxrpc_peer *rxrpc_alloc_peer(stru
+       peer = kzalloc(sizeof(struct rxrpc_peer), gfp);
+       if (peer) {
+               atomic_set(&peer->usage, 1);
+-              peer->local = local;
++              peer->local = rxrpc_get_local(local);
+               INIT_HLIST_HEAD(&peer->error_targets);
+               peer->service_conns = RB_ROOT;
+               seqlock_init(&peer->service_conn_lock);
+@@ -307,7 +307,6 @@ void rxrpc_new_incoming_peer(struct rxrp
+       unsigned long hash_key;
+       hash_key = rxrpc_peer_hash_key(local, &peer->srx);
+-      peer->local = local;
+       rxrpc_init_peer(rx, peer, hash_key);
+       spin_lock(&rxnet->peer_hash_lock);
+@@ -417,6 +416,7 @@ static void __rxrpc_put_peer(struct rxrp
+       list_del_init(&peer->keepalive_link);
+       spin_unlock_bh(&rxnet->peer_hash_lock);
++      rxrpc_put_local(peer->local);
+       kfree_rcu(peer, rcu);
+ }
+@@ -450,6 +450,7 @@ void rxrpc_put_peer_locked(struct rxrpc_
+       if (n == 0) {
+               hash_del_rcu(&peer->hash_link);
+               list_del_init(&peer->keepalive_link);
++              rxrpc_put_local(peer->local);
+               kfree_rcu(peer, rcu);
+       }
+ }
diff --git a/queue-5.3/sch_netem-fix-rcu-splat-in-netem_enqueue.patch b/queue-5.3/sch_netem-fix-rcu-splat-in-netem_enqueue.patch
new file mode 100644 (file)
index 0000000..ba6e65d
--- /dev/null
@@ -0,0 +1,102 @@
+From 159d2c7d8106177bd9a986fd005a311fe0d11285 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Tue, 24 Sep 2019 13:11:26 -0700
+Subject: sch_netem: fix rcu splat in netem_enqueue()
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit 159d2c7d8106177bd9a986fd005a311fe0d11285 upstream.
+
+qdisc_root() use from netem_enqueue() triggers a lockdep warning.
+
+__dev_queue_xmit() uses rcu_read_lock_bh() which is
+not equivalent to rcu_read_lock() + local_bh_disable_bh as far
+as lockdep is concerned.
+
+WARNING: suspicious RCU usage
+5.3.0-rc7+ #0 Not tainted
+-----------------------------
+include/net/sch_generic.h:492 suspicious rcu_dereference_check() usage!
+
+other info that might help us debug this:
+
+rcu_scheduler_active = 2, debug_locks = 1
+3 locks held by syz-executor427/8855:
+ #0: 00000000b5525c01 (rcu_read_lock_bh){....}, at: lwtunnel_xmit_redirect include/net/lwtunnel.h:92 [inline]
+ #0: 00000000b5525c01 (rcu_read_lock_bh){....}, at: ip_finish_output2+0x2dc/0x2570 net/ipv4/ip_output.c:214
+ #1: 00000000b5525c01 (rcu_read_lock_bh){....}, at: __dev_queue_xmit+0x20a/0x3650 net/core/dev.c:3804
+ #2: 00000000364bae92 (&(&sch->q.lock)->rlock){+.-.}, at: spin_lock include/linux/spinlock.h:338 [inline]
+ #2: 00000000364bae92 (&(&sch->q.lock)->rlock){+.-.}, at: __dev_xmit_skb net/core/dev.c:3502 [inline]
+ #2: 00000000364bae92 (&(&sch->q.lock)->rlock){+.-.}, at: __dev_queue_xmit+0x14b8/0x3650 net/core/dev.c:3838
+
+stack backtrace:
+CPU: 0 PID: 8855 Comm: syz-executor427 Not tainted 5.3.0-rc7+ #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0x172/0x1f0 lib/dump_stack.c:113
+ lockdep_rcu_suspicious+0x153/0x15d kernel/locking/lockdep.c:5357
+ qdisc_root include/net/sch_generic.h:492 [inline]
+ netem_enqueue+0x1cfb/0x2d80 net/sched/sch_netem.c:479
+ __dev_xmit_skb net/core/dev.c:3527 [inline]
+ __dev_queue_xmit+0x15d2/0x3650 net/core/dev.c:3838
+ dev_queue_xmit+0x18/0x20 net/core/dev.c:3902
+ neigh_hh_output include/net/neighbour.h:500 [inline]
+ neigh_output include/net/neighbour.h:509 [inline]
+ ip_finish_output2+0x1726/0x2570 net/ipv4/ip_output.c:228
+ __ip_finish_output net/ipv4/ip_output.c:308 [inline]
+ __ip_finish_output+0x5fc/0xb90 net/ipv4/ip_output.c:290
+ ip_finish_output+0x38/0x1f0 net/ipv4/ip_output.c:318
+ NF_HOOK_COND include/linux/netfilter.h:294 [inline]
+ ip_mc_output+0x292/0xf40 net/ipv4/ip_output.c:417
+ dst_output include/net/dst.h:436 [inline]
+ ip_local_out+0xbb/0x190 net/ipv4/ip_output.c:125
+ ip_send_skb+0x42/0xf0 net/ipv4/ip_output.c:1555
+ udp_send_skb.isra.0+0x6b2/0x1160 net/ipv4/udp.c:887
+ udp_sendmsg+0x1e96/0x2820 net/ipv4/udp.c:1174
+ inet_sendmsg+0x9e/0xe0 net/ipv4/af_inet.c:807
+ sock_sendmsg_nosec net/socket.c:637 [inline]
+ sock_sendmsg+0xd7/0x130 net/socket.c:657
+ ___sys_sendmsg+0x3e2/0x920 net/socket.c:2311
+ __sys_sendmmsg+0x1bf/0x4d0 net/socket.c:2413
+ __do_sys_sendmmsg net/socket.c:2442 [inline]
+ __se_sys_sendmmsg net/socket.c:2439 [inline]
+ __x64_sys_sendmmsg+0x9d/0x100 net/socket.c:2439
+ do_syscall_64+0xfd/0x6a0 arch/x86/entry/common.c:296
+ entry_SYSCALL_64_after_hwframe+0x49/0xbe
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/sch_generic.h |    5 +++++
+ net/sched/sch_netem.c     |    2 +-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+--- a/include/net/sch_generic.h
++++ b/include/net/sch_generic.h
+@@ -520,6 +520,11 @@ static inline struct Qdisc *qdisc_root(c
+       return q;
+ }
++static inline struct Qdisc *qdisc_root_bh(const struct Qdisc *qdisc)
++{
++      return rcu_dereference_bh(qdisc->dev_queue->qdisc);
++}
++
+ static inline struct Qdisc *qdisc_root_sleeping(const struct Qdisc *qdisc)
+ {
+       return qdisc->dev_queue->qdisc_sleeping;
+--- a/net/sched/sch_netem.c
++++ b/net/sched/sch_netem.c
+@@ -476,7 +476,7 @@ static int netem_enqueue(struct sk_buff
+        * skb will be queued.
+        */
+       if (count > 1 && (skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) {
+-              struct Qdisc *rootq = qdisc_root(sch);
++              struct Qdisc *rootq = qdisc_root_bh(sch);
+               u32 dupsave = q->duplicate; /* prevent duplicating a dup... */
+               q->duplicate = 0;
index 0bcacb6aafa588c4e66645a53e18ad41c4cfb8f3..f409a0799c17adeff6eb73a4400e2f7bf1758b49 100644 (file)
@@ -142,3 +142,16 @@ drm-amdgpu-fix-sdma-hang-when-performing-vkexample-test.patch
 nfs-fix-an-rcu-lock-leak-in-nfs4_refresh_delegation_stateid.patch
 io_uring-ensure-we-clear-io_kiocb-result-before-each-issue.patch
 iommu-vt-d-fix-panic-after-kexec-p-for-kdump.patch
+batman-adv-avoid-free-alloc-race-when-handling-ogm-buffer.patch
+llc-fix-sk_buff-leak-in-llc_sap_state_process.patch
+llc-fix-sk_buff-leak-in-llc_conn_service.patch
+rxrpc-fix-call-ref-leak.patch
+rxrpc-rxrpc_peer-needs-to-hold-a-ref-on-the-rxrpc_local-record.patch
+rxrpc-fix-trace-after-put-looking-at-the-put-peer-record.patch
+nfc-pn533-fix-use-after-free-and-memleaks.patch
+bonding-fix-potential-null-deref-in-bond_update_slave_arr.patch
+netfilter-conntrack-avoid-possible-false-sharing.patch
+blackhole_netdev-fix-syzkaller-reported-issue.patch
+net-usb-sr9800-fix-uninitialized-local-variable.patch
+sch_netem-fix-rcu-splat-in-netem_enqueue.patch
+net-sched-sch_sfb-don-t-call-qdisc_put-while-holding-tree-lock.patch