]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Sun, 25 Aug 2024 11:50:54 +0000 (07:50 -0400)
committerSasha Levin <sashal@kernel.org>
Sun, 25 Aug 2024 11:50:54 +0000 (07:50 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
16 files changed:
queue-5.4/bluetooth-hci_core-fix-le-quote-calculation.patch [new file with mode: 0644]
queue-5.4/bluetooth-hci_core-fix-not-handling-link-timeouts-pr.patch [new file with mode: 0644]
queue-5.4/bluetooth-make-use-of-__check_timeout-on-hci_sched_l.patch [new file with mode: 0644]
queue-5.4/ipv6-prevent-uaf-in-ip6_send_skb.patch [new file with mode: 0644]
queue-5.4/kcm-serialise-kcm_sendmsg-for-the-same-socket.patch [new file with mode: 0644]
queue-5.4/net-dsa-mv88e6xxx-fix-out-of-bound-access.patch [new file with mode: 0644]
queue-5.4/net-dsa-mv88e6xxx-global1_atu-add-helper-for-get-nex.patch [new file with mode: 0644]
queue-5.4/net-dsa-mv88e6xxx-global2-expose-atu-stats-register.patch [new file with mode: 0644]
queue-5.4/net-dsa-mv88e6xxx-read-fid-when-handling-atu-violati.patch [new file with mode: 0644]
queue-5.4/net-dsa-mv88e6xxx-replace-atu-violation-prints-with-.patch [new file with mode: 0644]
queue-5.4/net-xilinx-axienet-always-disable-promiscuous-mode.patch [new file with mode: 0644]
queue-5.4/net-xilinx-axienet-fix-dangling-multicast-addresses.patch [new file with mode: 0644]
queue-5.4/netem-fix-return-value-if-duplicate-enqueue-fails.patch [new file with mode: 0644]
queue-5.4/netfilter-nft_counter-synchronize-nft_counter_reset-.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/tc-testing-don-t-access-non-existent-variable-on-exc.patch [new file with mode: 0644]

diff --git a/queue-5.4/bluetooth-hci_core-fix-le-quote-calculation.patch b/queue-5.4/bluetooth-hci_core-fix-le-quote-calculation.patch
new file mode 100644 (file)
index 0000000..f6d4c67
--- /dev/null
@@ -0,0 +1,74 @@
+From a7451ea041d4572418cd16fd5114437ebbb6d32d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Aug 2024 11:22:08 -0400
+Subject: Bluetooth: hci_core: Fix LE quote calculation
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 932021a11805b9da4bd6abf66fe233cccd59fe0e ]
+
+Function hci_sched_le needs to update the respective counter variable
+inplace other the likes of hci_quote_sent would attempt to use the
+possible outdated value of conn->{le_cnt,acl_cnt}.
+
+Link: https://github.com/bluez/bluez/issues/915
+Fixes: 73d80deb7bdf ("Bluetooth: prioritizing data over HCI")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_core.c | 19 +++++++------------
+ 1 file changed, 7 insertions(+), 12 deletions(-)
+
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index b6243cb97e8ec..f1e8bda97c106 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -4245,19 +4245,19 @@ static void hci_sched_le(struct hci_dev *hdev)
+ {
+       struct hci_chan *chan;
+       struct sk_buff *skb;
+-      int quote, cnt, tmp;
++      int quote, *cnt, tmp;
+       BT_DBG("%s", hdev->name);
+       if (!hci_conn_num(hdev, LE_LINK))
+               return;
+-      cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
++      cnt = hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt;
+-      __check_timeout(hdev, cnt, LE_LINK);
++      __check_timeout(hdev, *cnt, LE_LINK);
+-      tmp = cnt;
+-      while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
++      tmp = *cnt;
++      while (*cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
+               u32 priority = (skb_peek(&chan->data_q))->priority;
+               while (quote-- && (skb = skb_peek(&chan->data_q))) {
+                       BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
+@@ -4272,18 +4272,13 @@ static void hci_sched_le(struct hci_dev *hdev)
+                       hci_send_frame(hdev, skb);
+                       hdev->le_last_tx = jiffies;
+-                      cnt--;
++                      (*cnt)--;
+                       chan->sent++;
+                       chan->conn->sent++;
+               }
+       }
+-      if (hdev->le_pkts)
+-              hdev->le_cnt = cnt;
+-      else
+-              hdev->acl_cnt = cnt;
+-
+-      if (cnt != tmp)
++      if (*cnt != tmp)
+               hci_prio_recalculate(hdev, LE_LINK);
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.4/bluetooth-hci_core-fix-not-handling-link-timeouts-pr.patch b/queue-5.4/bluetooth-hci_core-fix-not-handling-link-timeouts-pr.patch
new file mode 100644 (file)
index 0000000..fe88089
--- /dev/null
@@ -0,0 +1,105 @@
+From 26a1cb188edc9410baccc90df814b2dd1371e883 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Sep 2022 15:44:42 -0700
+Subject: Bluetooth: hci_core: Fix not handling link timeouts propertly
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 116523c8fac05d1d26f748fee7919a4ec5df67ea ]
+
+Change that introduced the use of __check_timeout did not account for
+link types properly, it always assumes ACL_LINK is used thus causing
+hdev->acl_last_tx to be used even in case of LE_LINK and then again
+uses ACL_LINK with hci_link_tx_to.
+
+To fix this __check_timeout now takes the link type as parameter and
+then procedure to use the right last_tx based on the link type and pass
+it to hci_link_tx_to.
+
+Fixes: 1b1d29e51499 ("Bluetooth: Make use of __check_timeout on hci_sched_le")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Tested-by: David Beinder <david@beinder.at>
+Stable-dep-of: 932021a11805 ("Bluetooth: hci_core: Fix LE quote calculation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_core.c | 34 +++++++++++++++++++++++-----------
+ 1 file changed, 23 insertions(+), 11 deletions(-)
+
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 6caef575c628c..b6243cb97e8ec 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -4055,15 +4055,27 @@ static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
+       return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
+ }
+-static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
++static void __check_timeout(struct hci_dev *hdev, unsigned int cnt, u8 type)
+ {
+-      if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
+-              /* ACL tx timeout must be longer than maximum
+-               * link supervision timeout (40.9 seconds) */
+-              if (!cnt && time_after(jiffies, hdev->acl_last_tx +
+-                                     HCI_ACL_TX_TIMEOUT))
+-                      hci_link_tx_to(hdev, ACL_LINK);
++      unsigned long last_tx;
++
++      if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
++              return;
++
++      switch (type) {
++      case LE_LINK:
++              last_tx = hdev->le_last_tx;
++              break;
++      default:
++              last_tx = hdev->acl_last_tx;
++              break;
+       }
++
++      /* tx timeout must be longer than maximum link supervision timeout
++       * (40.9 seconds)
++       */
++      if (!cnt && time_after(jiffies, last_tx + HCI_ACL_TX_TIMEOUT))
++              hci_link_tx_to(hdev, type);
+ }
+ static void hci_sched_acl_pkt(struct hci_dev *hdev)
+@@ -4073,7 +4085,7 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev)
+       struct sk_buff *skb;
+       int quote;
+-      __check_timeout(hdev, cnt);
++      __check_timeout(hdev, cnt, ACL_LINK);
+       while (hdev->acl_cnt &&
+              (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
+@@ -4112,8 +4124,6 @@ static void hci_sched_acl_blk(struct hci_dev *hdev)
+       int quote;
+       u8 type;
+-      __check_timeout(hdev, cnt);
+-
+       BT_DBG("%s", hdev->name);
+       if (hdev->dev_type == HCI_AMP)
+@@ -4121,6 +4131,8 @@ static void hci_sched_acl_blk(struct hci_dev *hdev)
+       else
+               type = ACL_LINK;
++      __check_timeout(hdev, cnt, type);
++
+       while (hdev->block_cnt > 0 &&
+              (chan = hci_chan_sent(hdev, type, &quote))) {
+               u32 priority = (skb_peek(&chan->data_q))->priority;
+@@ -4242,7 +4254,7 @@ static void hci_sched_le(struct hci_dev *hdev)
+       cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
+-      __check_timeout(hdev, cnt);
++      __check_timeout(hdev, cnt, LE_LINK);
+       tmp = cnt;
+       while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
+-- 
+2.43.0
+
diff --git a/queue-5.4/bluetooth-make-use-of-__check_timeout-on-hci_sched_l.patch b/queue-5.4/bluetooth-make-use-of-__check_timeout-on-hci_sched_l.patch
new file mode 100644 (file)
index 0000000..048953f
--- /dev/null
@@ -0,0 +1,46 @@
+From d5b21c11457cefc52404a638e22e9d41f469ce7e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2020 13:02:18 -0800
+Subject: Bluetooth: Make use of __check_timeout on hci_sched_le
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 1b1d29e5149990e44634b2e681de71effd463591 ]
+
+This reuse __check_timeout on hci_sched_le following the same logic
+used hci_sched_acl.
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Stable-dep-of: 932021a11805 ("Bluetooth: hci_core: Fix LE quote calculation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_core.c | 11 +++--------
+ 1 file changed, 3 insertions(+), 8 deletions(-)
+
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 71a7e42097cc0..6caef575c628c 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -4240,15 +4240,10 @@ static void hci_sched_le(struct hci_dev *hdev)
+       if (!hci_conn_num(hdev, LE_LINK))
+               return;
+-      if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
+-              /* LE tx timeout must be longer than maximum
+-               * link supervision timeout (40.9 seconds) */
+-              if (!hdev->le_cnt && hdev->le_pkts &&
+-                  time_after(jiffies, hdev->le_last_tx + HZ * 45))
+-                      hci_link_tx_to(hdev, LE_LINK);
+-      }
+-
+       cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
++
++      __check_timeout(hdev, cnt);
++
+       tmp = cnt;
+       while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
+               u32 priority = (skb_peek(&chan->data_q))->priority;
+-- 
+2.43.0
+
diff --git a/queue-5.4/ipv6-prevent-uaf-in-ip6_send_skb.patch b/queue-5.4/ipv6-prevent-uaf-in-ip6_send_skb.patch
new file mode 100644 (file)
index 0000000..ebfffae
--- /dev/null
@@ -0,0 +1,158 @@
+From 7abc155cc65839ff1ef143675e75c395bd0b9f90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Aug 2024 16:08:57 +0000
+Subject: ipv6: prevent UAF in ip6_send_skb()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit faa389b2fbaaec7fd27a390b4896139f9da662e3 ]
+
+syzbot reported an UAF in ip6_send_skb() [1]
+
+After ip6_local_out() has returned, we no longer can safely
+dereference rt, unless we hold rcu_read_lock().
+
+A similar issue has been fixed in commit
+a688caa34beb ("ipv6: take rcu lock in rawv6_send_hdrinc()")
+
+Another potential issue in ip6_finish_output2() is handled in a
+separate patch.
+
+[1]
+ BUG: KASAN: slab-use-after-free in ip6_send_skb+0x18d/0x230 net/ipv6/ip6_output.c:1964
+Read of size 8 at addr ffff88806dde4858 by task syz.1.380/6530
+
+CPU: 1 UID: 0 PID: 6530 Comm: syz.1.380 Not tainted 6.11.0-rc3-syzkaller-00306-gdf6cbc62cc9b #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/06/2024
+Call Trace:
+ <TASK>
+  __dump_stack lib/dump_stack.c:93 [inline]
+  dump_stack_lvl+0x241/0x360 lib/dump_stack.c:119
+  print_address_description mm/kasan/report.c:377 [inline]
+  print_report+0x169/0x550 mm/kasan/report.c:488
+  kasan_report+0x143/0x180 mm/kasan/report.c:601
+  ip6_send_skb+0x18d/0x230 net/ipv6/ip6_output.c:1964
+  rawv6_push_pending_frames+0x75c/0x9e0 net/ipv6/raw.c:588
+  rawv6_sendmsg+0x19c7/0x23c0 net/ipv6/raw.c:926
+  sock_sendmsg_nosec net/socket.c:730 [inline]
+  __sock_sendmsg+0x1a6/0x270 net/socket.c:745
+  sock_write_iter+0x2dd/0x400 net/socket.c:1160
+ do_iter_readv_writev+0x60a/0x890
+  vfs_writev+0x37c/0xbb0 fs/read_write.c:971
+  do_writev+0x1b1/0x350 fs/read_write.c:1018
+  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+  do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f936bf79e79
+Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f936cd7f038 EFLAGS: 00000246 ORIG_RAX: 0000000000000014
+RAX: ffffffffffffffda RBX: 00007f936c115f80 RCX: 00007f936bf79e79
+RDX: 0000000000000001 RSI: 0000000020000040 RDI: 0000000000000004
+RBP: 00007f936bfe7916 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+R13: 0000000000000000 R14: 00007f936c115f80 R15: 00007fff2860a7a8
+ </TASK>
+
+Allocated by task 6530:
+  kasan_save_stack mm/kasan/common.c:47 [inline]
+  kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
+  unpoison_slab_object mm/kasan/common.c:312 [inline]
+  __kasan_slab_alloc+0x66/0x80 mm/kasan/common.c:338
+  kasan_slab_alloc include/linux/kasan.h:201 [inline]
+  slab_post_alloc_hook mm/slub.c:3988 [inline]
+  slab_alloc_node mm/slub.c:4037 [inline]
+  kmem_cache_alloc_noprof+0x135/0x2a0 mm/slub.c:4044
+  dst_alloc+0x12b/0x190 net/core/dst.c:89
+  ip6_blackhole_route+0x59/0x340 net/ipv6/route.c:2670
+  make_blackhole net/xfrm/xfrm_policy.c:3120 [inline]
+  xfrm_lookup_route+0xd1/0x1c0 net/xfrm/xfrm_policy.c:3313
+  ip6_dst_lookup_flow+0x13e/0x180 net/ipv6/ip6_output.c:1257
+  rawv6_sendmsg+0x1283/0x23c0 net/ipv6/raw.c:898
+  sock_sendmsg_nosec net/socket.c:730 [inline]
+  __sock_sendmsg+0x1a6/0x270 net/socket.c:745
+  ____sys_sendmsg+0x525/0x7d0 net/socket.c:2597
+  ___sys_sendmsg net/socket.c:2651 [inline]
+  __sys_sendmsg+0x2b0/0x3a0 net/socket.c:2680
+  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+  do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Freed by task 45:
+  kasan_save_stack mm/kasan/common.c:47 [inline]
+  kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
+  kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:579
+  poison_slab_object+0xe0/0x150 mm/kasan/common.c:240
+  __kasan_slab_free+0x37/0x60 mm/kasan/common.c:256
+  kasan_slab_free include/linux/kasan.h:184 [inline]
+  slab_free_hook mm/slub.c:2252 [inline]
+  slab_free mm/slub.c:4473 [inline]
+  kmem_cache_free+0x145/0x350 mm/slub.c:4548
+  dst_destroy+0x2ac/0x460 net/core/dst.c:124
+  rcu_do_batch kernel/rcu/tree.c:2569 [inline]
+  rcu_core+0xafd/0x1830 kernel/rcu/tree.c:2843
+  handle_softirqs+0x2c4/0x970 kernel/softirq.c:554
+  __do_softirq kernel/softirq.c:588 [inline]
+  invoke_softirq kernel/softirq.c:428 [inline]
+  __irq_exit_rcu+0xf4/0x1c0 kernel/softirq.c:637
+  irq_exit_rcu+0x9/0x30 kernel/softirq.c:649
+  instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1043 [inline]
+  sysvec_apic_timer_interrupt+0xa6/0xc0 arch/x86/kernel/apic/apic.c:1043
+  asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:702
+
+Last potentially related work creation:
+  kasan_save_stack+0x3f/0x60 mm/kasan/common.c:47
+  __kasan_record_aux_stack+0xac/0xc0 mm/kasan/generic.c:541
+  __call_rcu_common kernel/rcu/tree.c:3106 [inline]
+  call_rcu+0x167/0xa70 kernel/rcu/tree.c:3210
+  refdst_drop include/net/dst.h:263 [inline]
+  skb_dst_drop include/net/dst.h:275 [inline]
+  nf_ct_frag6_queue net/ipv6/netfilter/nf_conntrack_reasm.c:306 [inline]
+  nf_ct_frag6_gather+0xb9a/0x2080 net/ipv6/netfilter/nf_conntrack_reasm.c:485
+  ipv6_defrag+0x2c8/0x3c0 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c:67
+  nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline]
+  nf_hook_slow+0xc3/0x220 net/netfilter/core.c:626
+  nf_hook include/linux/netfilter.h:269 [inline]
+  __ip6_local_out+0x6fa/0x800 net/ipv6/output_core.c:143
+  ip6_local_out+0x26/0x70 net/ipv6/output_core.c:153
+  ip6_send_skb+0x112/0x230 net/ipv6/ip6_output.c:1959
+  rawv6_push_pending_frames+0x75c/0x9e0 net/ipv6/raw.c:588
+  rawv6_sendmsg+0x19c7/0x23c0 net/ipv6/raw.c:926
+  sock_sendmsg_nosec net/socket.c:730 [inline]
+  __sock_sendmsg+0x1a6/0x270 net/socket.c:745
+  sock_write_iter+0x2dd/0x400 net/socket.c:1160
+ do_iter_readv_writev+0x60a/0x890
+
+Fixes: 0625491493d9 ("ipv6: ip6_push_pending_frames() should increment IPSTATS_MIB_OUTDISCARDS")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20240820160859.3786976-2-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_output.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index c67d634dccd47..a34a562b0954d 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1882,6 +1882,7 @@ int ip6_send_skb(struct sk_buff *skb)
+       struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
+       int err;
++      rcu_read_lock();
+       err = ip6_local_out(net, skb->sk, skb);
+       if (err) {
+               if (err > 0)
+@@ -1891,6 +1892,7 @@ int ip6_send_skb(struct sk_buff *skb)
+                                     IPSTATS_MIB_OUTDISCARDS);
+       }
++      rcu_read_unlock();
+       return err;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.4/kcm-serialise-kcm_sendmsg-for-the-same-socket.patch b/queue-5.4/kcm-serialise-kcm_sendmsg-for-the-same-socket.patch
new file mode 100644 (file)
index 0000000..f2bed66
--- /dev/null
@@ -0,0 +1,223 @@
+From 6c92f1781af4b537690a2360c90db4be07929335 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Aug 2024 15:04:37 -0700
+Subject: kcm: Serialise kcm_sendmsg() for the same socket.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 807067bf014d4a3ae2cc55bd3de16f22a01eb580 ]
+
+syzkaller reported UAF in kcm_release(). [0]
+
+The scenario is
+
+  1. Thread A builds a skb with MSG_MORE and sets kcm->seq_skb.
+
+  2. Thread A resumes building skb from kcm->seq_skb but is blocked
+     by sk_stream_wait_memory()
+
+  3. Thread B calls sendmsg() concurrently, finishes building kcm->seq_skb
+     and puts the skb to the write queue
+
+  4. Thread A faces an error and finally frees skb that is already in the
+     write queue
+
+  5. kcm_release() does double-free the skb in the write queue
+
+When a thread is building a MSG_MORE skb, another thread must not touch it.
+
+Let's add a per-sk mutex and serialise kcm_sendmsg().
+
+[0]:
+BUG: KASAN: slab-use-after-free in __skb_unlink include/linux/skbuff.h:2366 [inline]
+BUG: KASAN: slab-use-after-free in __skb_dequeue include/linux/skbuff.h:2385 [inline]
+BUG: KASAN: slab-use-after-free in __skb_queue_purge_reason include/linux/skbuff.h:3175 [inline]
+BUG: KASAN: slab-use-after-free in __skb_queue_purge include/linux/skbuff.h:3181 [inline]
+BUG: KASAN: slab-use-after-free in kcm_release+0x170/0x4c8 net/kcm/kcmsock.c:1691
+Read of size 8 at addr ffff0000ced0fc80 by task syz-executor329/6167
+
+CPU: 1 PID: 6167 Comm: syz-executor329 Tainted: G    B              6.8.0-rc5-syzkaller-g9abbc24128bc #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/25/2024
+Call trace:
+ dump_backtrace+0x1b8/0x1e4 arch/arm64/kernel/stacktrace.c:291
+ show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:298
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0xd0/0x124 lib/dump_stack.c:106
+ print_address_description mm/kasan/report.c:377 [inline]
+ print_report+0x178/0x518 mm/kasan/report.c:488
+ kasan_report+0xd8/0x138 mm/kasan/report.c:601
+ __asan_report_load8_noabort+0x20/0x2c mm/kasan/report_generic.c:381
+ __skb_unlink include/linux/skbuff.h:2366 [inline]
+ __skb_dequeue include/linux/skbuff.h:2385 [inline]
+ __skb_queue_purge_reason include/linux/skbuff.h:3175 [inline]
+ __skb_queue_purge include/linux/skbuff.h:3181 [inline]
+ kcm_release+0x170/0x4c8 net/kcm/kcmsock.c:1691
+ __sock_release net/socket.c:659 [inline]
+ sock_close+0xa4/0x1e8 net/socket.c:1421
+ __fput+0x30c/0x738 fs/file_table.c:376
+ ____fput+0x20/0x30 fs/file_table.c:404
+ task_work_run+0x230/0x2e0 kernel/task_work.c:180
+ exit_task_work include/linux/task_work.h:38 [inline]
+ do_exit+0x618/0x1f64 kernel/exit.c:871
+ do_group_exit+0x194/0x22c kernel/exit.c:1020
+ get_signal+0x1500/0x15ec kernel/signal.c:2893
+ do_signal+0x23c/0x3b44 arch/arm64/kernel/signal.c:1249
+ do_notify_resume+0x74/0x1f4 arch/arm64/kernel/entry-common.c:148
+ exit_to_user_mode_prepare arch/arm64/kernel/entry-common.c:169 [inline]
+ exit_to_user_mode arch/arm64/kernel/entry-common.c:178 [inline]
+ el0_svc+0xac/0x168 arch/arm64/kernel/entry-common.c:713
+ el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730
+ el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598
+
+Allocated by task 6166:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x40/0x78 mm/kasan/common.c:68
+ kasan_save_alloc_info+0x70/0x84 mm/kasan/generic.c:626
+ unpoison_slab_object mm/kasan/common.c:314 [inline]
+ __kasan_slab_alloc+0x74/0x8c mm/kasan/common.c:340
+ kasan_slab_alloc include/linux/kasan.h:201 [inline]
+ slab_post_alloc_hook mm/slub.c:3813 [inline]
+ slab_alloc_node mm/slub.c:3860 [inline]
+ kmem_cache_alloc_node+0x204/0x4c0 mm/slub.c:3903
+ __alloc_skb+0x19c/0x3d8 net/core/skbuff.c:641
+ alloc_skb include/linux/skbuff.h:1296 [inline]
+ kcm_sendmsg+0x1d3c/0x2124 net/kcm/kcmsock.c:783
+ sock_sendmsg_nosec net/socket.c:730 [inline]
+ __sock_sendmsg net/socket.c:745 [inline]
+ sock_sendmsg+0x220/0x2c0 net/socket.c:768
+ splice_to_socket+0x7cc/0xd58 fs/splice.c:889
+ do_splice_from fs/splice.c:941 [inline]
+ direct_splice_actor+0xec/0x1d8 fs/splice.c:1164
+ splice_direct_to_actor+0x438/0xa0c fs/splice.c:1108
+ do_splice_direct_actor fs/splice.c:1207 [inline]
+ do_splice_direct+0x1e4/0x304 fs/splice.c:1233
+ do_sendfile+0x460/0xb3c fs/read_write.c:1295
+ __do_sys_sendfile64 fs/read_write.c:1362 [inline]
+ __se_sys_sendfile64 fs/read_write.c:1348 [inline]
+ __arm64_sys_sendfile64+0x160/0x3b4 fs/read_write.c:1348
+ __invoke_syscall arch/arm64/kernel/syscall.c:37 [inline]
+ invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:51
+ el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:136
+ do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:155
+ el0_svc+0x54/0x168 arch/arm64/kernel/entry-common.c:712
+ el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730
+ el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598
+
+Freed by task 6167:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x40/0x78 mm/kasan/common.c:68
+ kasan_save_free_info+0x5c/0x74 mm/kasan/generic.c:640
+ poison_slab_object+0x124/0x18c mm/kasan/common.c:241
+ __kasan_slab_free+0x3c/0x78 mm/kasan/common.c:257
+ kasan_slab_free include/linux/kasan.h:184 [inline]
+ slab_free_hook mm/slub.c:2121 [inline]
+ slab_free mm/slub.c:4299 [inline]
+ kmem_cache_free+0x15c/0x3d4 mm/slub.c:4363
+ kfree_skbmem+0x10c/0x19c
+ __kfree_skb net/core/skbuff.c:1109 [inline]
+ kfree_skb_reason+0x240/0x6f4 net/core/skbuff.c:1144
+ kfree_skb include/linux/skbuff.h:1244 [inline]
+ kcm_release+0x104/0x4c8 net/kcm/kcmsock.c:1685
+ __sock_release net/socket.c:659 [inline]
+ sock_close+0xa4/0x1e8 net/socket.c:1421
+ __fput+0x30c/0x738 fs/file_table.c:376
+ ____fput+0x20/0x30 fs/file_table.c:404
+ task_work_run+0x230/0x2e0 kernel/task_work.c:180
+ exit_task_work include/linux/task_work.h:38 [inline]
+ do_exit+0x618/0x1f64 kernel/exit.c:871
+ do_group_exit+0x194/0x22c kernel/exit.c:1020
+ get_signal+0x1500/0x15ec kernel/signal.c:2893
+ do_signal+0x23c/0x3b44 arch/arm64/kernel/signal.c:1249
+ do_notify_resume+0x74/0x1f4 arch/arm64/kernel/entry-common.c:148
+ exit_to_user_mode_prepare arch/arm64/kernel/entry-common.c:169 [inline]
+ exit_to_user_mode arch/arm64/kernel/entry-common.c:178 [inline]
+ el0_svc+0xac/0x168 arch/arm64/kernel/entry-common.c:713
+ el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730
+ el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598
+
+The buggy address belongs to the object at ffff0000ced0fc80
+ which belongs to the cache skbuff_head_cache of size 240
+The buggy address is located 0 bytes inside of
+ freed 240-byte region [ffff0000ced0fc80, ffff0000ced0fd70)
+
+The buggy address belongs to the physical page:
+page:00000000d35f4ae4 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10ed0f
+flags: 0x5ffc00000000800(slab|node=0|zone=2|lastcpupid=0x7ff)
+page_type: 0xffffffff()
+raw: 05ffc00000000800 ffff0000c1cbf640 fffffdffc3423100 dead000000000004
+raw: 0000000000000000 00000000000c000c 00000001ffffffff 0000000000000000
+page dumped because: kasan: bad access detected
+
+Memory state around the buggy address:
+ ffff0000ced0fb80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff0000ced0fc00: fb fb fb fb fb fb fc fc fc fc fc fc fc fc fc fc
+>ffff0000ced0fc80: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+                   ^
+ ffff0000ced0fd00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fc fc
+ ffff0000ced0fd80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
+
+Fixes: ab7ac4eb9832 ("kcm: Kernel Connection Multiplexor module")
+Reported-by: syzbot+b72d86aa5df17ce74c60@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=b72d86aa5df17ce74c60
+Tested-by: syzbot+b72d86aa5df17ce74c60@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20240815220437.69511-1-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/kcm.h | 1 +
+ net/kcm/kcmsock.c | 4 ++++
+ 2 files changed, 5 insertions(+)
+
+diff --git a/include/net/kcm.h b/include/net/kcm.h
+index 2d704f8f49059..8e8252e08a9ce 100644
+--- a/include/net/kcm.h
++++ b/include/net/kcm.h
+@@ -70,6 +70,7 @@ struct kcm_sock {
+       struct work_struct tx_work;
+       struct list_head wait_psock_list;
+       struct sk_buff *seq_skb;
++      struct mutex tx_mutex;
+       u32 tx_stopped : 1;
+       /* Don't use bit fields here, these are set under different locks */
+diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
+index 920b0ebf1cb80..50dceed77ba66 100644
+--- a/net/kcm/kcmsock.c
++++ b/net/kcm/kcmsock.c
+@@ -913,6 +913,7 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
+                 !(msg->msg_flags & MSG_MORE) : !!(msg->msg_flags & MSG_EOR);
+       int err = -EPIPE;
++      mutex_lock(&kcm->tx_mutex);
+       lock_sock(sk);
+       /* Per tcp_sendmsg this should be in poll */
+@@ -1061,6 +1062,7 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
+       KCM_STATS_ADD(kcm->stats.tx_bytes, copied);
+       release_sock(sk);
++      mutex_unlock(&kcm->tx_mutex);
+       return copied;
+ out_error:
+@@ -1086,6 +1088,7 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
+               sk->sk_write_space(sk);
+       release_sock(sk);
++      mutex_unlock(&kcm->tx_mutex);
+       return err;
+ }
+@@ -1328,6 +1331,7 @@ static void init_kcm_sock(struct kcm_sock *kcm, struct kcm_mux *mux)
+       spin_unlock_bh(&mux->lock);
+       INIT_WORK(&kcm->tx_work, kcm_tx_work);
++      mutex_init(&kcm->tx_mutex);
+       spin_lock_bh(&mux->rx_lock);
+       kcm_rcv_ready(kcm);
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-dsa-mv88e6xxx-fix-out-of-bound-access.patch b/queue-5.4/net-dsa-mv88e6xxx-fix-out-of-bound-access.patch
new file mode 100644 (file)
index 0000000..2891477
--- /dev/null
@@ -0,0 +1,39 @@
+From 7ba0a3598cbf0e7919e81c456ffff62e3282ad3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Aug 2024 19:52:50 -0400
+Subject: net: dsa: mv88e6xxx: Fix out-of-bound access
+
+From: Joseph Huang <Joseph.Huang@garmin.com>
+
+[ Upstream commit 528876d867a23b5198022baf2e388052ca67c952 ]
+
+If an ATU violation was caused by a CPU Load operation, the SPID could
+be larger than DSA_MAX_PORTS (the size of mv88e6xxx_chip.ports[] array).
+
+Fixes: 75c05a74e745 ("net: dsa: mv88e6xxx: Fix counting of ATU violations")
+Signed-off-by: Joseph Huang <Joseph.Huang@garmin.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20240819235251.1331763-1-Joseph.Huang@garmin.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/global1_atu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/global1_atu.c b/drivers/net/dsa/mv88e6xxx/global1_atu.c
+index 2b314b416256d..f2e07d903aa73 100644
+--- a/drivers/net/dsa/mv88e6xxx/global1_atu.c
++++ b/drivers/net/dsa/mv88e6xxx/global1_atu.c
+@@ -421,7 +421,8 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
+               trace_mv88e6xxx_atu_full_violation(chip->dev, spid,
+                                                  entry.portvec, entry.mac,
+                                                  fid);
+-              chip->ports[spid].atu_full_violation++;
++              if (spid < ARRAY_SIZE(chip->ports))
++                      chip->ports[spid].atu_full_violation++;
+       }
+       mv88e6xxx_reg_unlock(chip);
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-dsa-mv88e6xxx-global1_atu-add-helper-for-get-nex.patch b/queue-5.4/net-dsa-mv88e6xxx-global1_atu-add-helper-for-get-nex.patch
new file mode 100644 (file)
index 0000000..4ccd8ec
--- /dev/null
@@ -0,0 +1,90 @@
+From 742d1008be3ab74d96b8142e7882f92096f72096 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2019 01:13:00 +0100
+Subject: net: dsa: mv88e6xxx: global1_atu: Add helper for get next
+
+From: Andrew Lunn <andrew@lunn.ch>
+
+[ Upstream commit c5f299d592617847124900d75e5765cb0368ffae ]
+
+When retrieving the ATU statistics, and ATU get next has to be
+performed to trigger the ATU to collect the statistics. Export a
+helper from global1_atu to perform this.
+
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 528876d867a2 ("net: dsa: mv88e6xxx: Fix out-of-bound access")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/global1.h     |  1 +
+ drivers/net/dsa/mv88e6xxx/global1_atu.c |  5 +++++
+ drivers/net/dsa/mv88e6xxx/global2.c     | 11 ++---------
+ drivers/net/dsa/mv88e6xxx/global2.h     |  2 +-
+ 4 files changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h
+index 0ae96a1e919b6..dc44e197817a8 100644
+--- a/drivers/net/dsa/mv88e6xxx/global1.h
++++ b/drivers/net/dsa/mv88e6xxx/global1.h
+@@ -339,5 +339,6 @@ int mv88e6390_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
+ int mv88e6xxx_g1_vtu_flush(struct mv88e6xxx_chip *chip);
+ int mv88e6xxx_g1_vtu_prob_irq_setup(struct mv88e6xxx_chip *chip);
+ void mv88e6xxx_g1_vtu_prob_irq_free(struct mv88e6xxx_chip *chip);
++int mv88e6xxx_g1_atu_get_next(struct mv88e6xxx_chip *chip, u16 fid);
+ #endif /* _MV88E6XXX_GLOBAL1_H */
+diff --git a/drivers/net/dsa/mv88e6xxx/global1_atu.c b/drivers/net/dsa/mv88e6xxx/global1_atu.c
+index 792a96ef418ff..d655a96f27f0a 100644
+--- a/drivers/net/dsa/mv88e6xxx/global1_atu.c
++++ b/drivers/net/dsa/mv88e6xxx/global1_atu.c
+@@ -122,6 +122,11 @@ static int mv88e6xxx_g1_atu_op(struct mv88e6xxx_chip *chip, u16 fid, u16 op)
+       return mv88e6xxx_g1_atu_op_wait(chip);
+ }
++int mv88e6xxx_g1_atu_get_next(struct mv88e6xxx_chip *chip, u16 fid)
++{
++      return mv88e6xxx_g1_atu_op(chip, fid, MV88E6XXX_G1_ATU_OP_GET_NEXT_DB);
++}
++
+ /* Offset 0x0C: ATU Data Register */
+ static int mv88e6xxx_g1_atu_data_read(struct mv88e6xxx_chip *chip,
+diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c
+index 6059c244373c8..4d4bd4a162815 100644
+--- a/drivers/net/dsa/mv88e6xxx/global2.c
++++ b/drivers/net/dsa/mv88e6xxx/global2.c
+@@ -288,16 +288,9 @@ int mv88e6xxx_g2_atu_stats_set(struct mv88e6xxx_chip *chip, u16 kind, u16 bin)
+                                 kind | bin);
+ }
+-int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip)
++int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip, u16 *stats)
+ {
+-      int err;
+-      u16 val;
+-
+-      err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_ATU_STATS, &val);
+-      if (err)
+-              return err;
+-
+-      return val & MV88E6XXX_G2_ATU_STATS_MASK;
++      return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_ATU_STATS, stats);
+ }
+ /* Offset 0x0F: Priority Override Table */
+diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h
+index 0e0ecf78f5ea7..a0cc40e7c2508 100644
+--- a/drivers/net/dsa/mv88e6xxx/global2.h
++++ b/drivers/net/dsa/mv88e6xxx/global2.h
+@@ -364,7 +364,7 @@ extern const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops;
+ int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
+                                     bool external);
+ int mv88e6xxx_g2_atu_stats_set(struct mv88e6xxx_chip *chip, u16 kind, u16 bin);
+-int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip);
++int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip, u16 *stats);
+ #else /* !CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-dsa-mv88e6xxx-global2-expose-atu-stats-register.patch b/queue-5.4/net-dsa-mv88e6xxx-global2-expose-atu-stats-register.patch
new file mode 100644 (file)
index 0000000..f367f27
--- /dev/null
@@ -0,0 +1,103 @@
+From c6749d0d346d802ab3585ae2891a0703b0b451b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2019 01:12:59 +0100
+Subject: net: dsa: mv88e6xxx: global2: Expose ATU stats register
+
+From: Andrew Lunn <andrew@lunn.ch>
+
+[ Upstream commit 6239a386e784aed13c3ead54c3992ebcb0512d5f ]
+
+Add helpers to set/get the ATU statistics register.
+
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 528876d867a2 ("net: dsa: mv88e6xxx: Fix out-of-bound access")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/global2.c | 20 ++++++++++++++++++++
+ drivers/net/dsa/mv88e6xxx/global2.h | 24 +++++++++++++++++++++++-
+ 2 files changed, 43 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c
+index 7674b0b8cc707..6059c244373c8 100644
+--- a/drivers/net/dsa/mv88e6xxx/global2.c
++++ b/drivers/net/dsa/mv88e6xxx/global2.c
+@@ -280,6 +280,26 @@ int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
+       return err;
+ }
++/* Offset 0x0E: ATU Statistics */
++
++int mv88e6xxx_g2_atu_stats_set(struct mv88e6xxx_chip *chip, u16 kind, u16 bin)
++{
++      return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_ATU_STATS,
++                                kind | bin);
++}
++
++int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip)
++{
++      int err;
++      u16 val;
++
++      err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_ATU_STATS, &val);
++      if (err)
++              return err;
++
++      return val & MV88E6XXX_G2_ATU_STATS_MASK;
++}
++
+ /* Offset 0x0F: Priority Override Table */
+ static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer,
+diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h
+index 12807e52ecea1..0e0ecf78f5ea7 100644
+--- a/drivers/net/dsa/mv88e6xxx/global2.h
++++ b/drivers/net/dsa/mv88e6xxx/global2.h
+@@ -113,7 +113,16 @@
+ #define MV88E6XXX_G2_SWITCH_MAC_DATA_MASK     0x00ff
+ /* Offset 0x0E: ATU Stats Register */
+-#define MV88E6XXX_G2_ATU_STATS                0x0e
++#define MV88E6XXX_G2_ATU_STATS                                0x0e
++#define MV88E6XXX_G2_ATU_STATS_BIN_0                  (0x0 << 14)
++#define MV88E6XXX_G2_ATU_STATS_BIN_1                  (0x1 << 14)
++#define MV88E6XXX_G2_ATU_STATS_BIN_2                  (0x2 << 14)
++#define MV88E6XXX_G2_ATU_STATS_BIN_3                  (0x3 << 14)
++#define MV88E6XXX_G2_ATU_STATS_MODE_ALL                       (0x0 << 12)
++#define MV88E6XXX_G2_ATU_STATS_MODE_ALL_DYNAMIC               (0x1 << 12)
++#define MV88E6XXX_G2_ATU_STATS_MODE_FID_ALL           (0x2 << 12)
++#define MV88E6XXX_G2_ATU_STATS_MODE_FID_ALL_DYNAMIC   (0x3 << 12)
++#define MV88E6XXX_G2_ATU_STATS_MASK                   0x0fff
+ /* Offset 0x0F: Priority Override Table */
+ #define MV88E6XXX_G2_PRIO_OVERRIDE            0x0f
+@@ -354,6 +363,8 @@ extern const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops;
+ int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
+                                     bool external);
++int mv88e6xxx_g2_atu_stats_set(struct mv88e6xxx_chip *chip, u16 kind, u16 bin);
++int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip);
+ #else /* !CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */
+@@ -516,6 +527,17 @@ static inline int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip,
+       return -EOPNOTSUPP;
+ }
++static inline int mv88e6xxx_g2_atu_stats_set(struct mv88e6xxx_chip *chip,
++                                           u16 kind, u16 bin)
++{
++      return -EOPNOTSUPP;
++}
++
++static inline int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip)
++{
++      return -EOPNOTSUPP;
++}
++
+ #endif /* CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */
+ #endif /* _MV88E6XXX_GLOBAL2_H */
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-dsa-mv88e6xxx-read-fid-when-handling-atu-violati.patch b/queue-5.4/net-dsa-mv88e6xxx-read-fid-when-handling-atu-violati.patch
new file mode 100644 (file)
index 0000000..f1d7740
--- /dev/null
@@ -0,0 +1,175 @@
+From cd071baccbf871147b37508c4d26d2e5509449b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 19:28:15 +0200
+Subject: net: dsa: mv88e6xxx: read FID when handling ATU violations
+
+From: Hans J. Schultz <netdev@kapio-technology.com>
+
+[ Upstream commit 4bf24ad09bc0b05e97fb48b962b2c9246fc76727 ]
+
+When an ATU violation occurs, the switch uses the ATU FID register to
+report the FID of the MAC address that incurred the violation. It would
+be good for the driver to know the FID value for purposes such as
+logging and CPU-based authentication.
+
+Up until now, the driver has been calling the mv88e6xxx_g1_atu_op()
+function to read ATU violations, but that doesn't do exactly what we
+want, namely it calls mv88e6xxx_g1_atu_fid_write() with FID 0.
+(side note, the documentation for the ATU Get/Clear Violation command
+says that writes to the ATU FID register have no effect before the
+operation starts, it's only that we disregard the value that this
+register provides once the operation completes)
+
+So mv88e6xxx_g1_atu_fid_write() is not what we want, but rather
+mv88e6xxx_g1_atu_fid_read(). However, the latter doesn't exist, we need
+to write it.
+
+The remainder of mv88e6xxx_g1_atu_op() except for
+mv88e6xxx_g1_atu_fid_write() is still needed, namely to send a
+GET_CLR_VIOLATION command to the ATU. In principle we could have still
+kept calling mv88e6xxx_g1_atu_op(), but the MDIO writes to the ATU FID
+register are pointless, but in the interest of doing less CPU work per
+interrupt, write a new function called mv88e6xxx_g1_read_atu_violation()
+and call it.
+
+The FID will be the port default FID as set by mv88e6xxx_port_set_fid()
+if the VID from the packet cannot be found in the VTU. Otherwise it is
+the FID derived from the VTU entry associated with that VID.
+
+Signed-off-by: Hans J. Schultz <netdev@kapio-technology.com>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 528876d867a2 ("net: dsa: mv88e6xxx: Fix out-of-bound access")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/global1_atu.c | 72 +++++++++++++++++++++----
+ 1 file changed, 61 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/global1_atu.c b/drivers/net/dsa/mv88e6xxx/global1_atu.c
+index d655a96f27f0a..13ca45bf0f0bb 100644
+--- a/drivers/net/dsa/mv88e6xxx/global1_atu.c
++++ b/drivers/net/dsa/mv88e6xxx/global1_atu.c
+@@ -82,6 +82,19 @@ static int mv88e6xxx_g1_atu_op_wait(struct mv88e6xxx_chip *chip)
+       return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_ATU_OP, bit, 0);
+ }
++static int mv88e6xxx_g1_read_atu_violation(struct mv88e6xxx_chip *chip)
++{
++      int err;
++
++      err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_ATU_OP,
++                               MV88E6XXX_G1_ATU_OP_BUSY |
++                               MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION);
++      if (err)
++              return err;
++
++      return mv88e6xxx_g1_atu_op_wait(chip);
++}
++
+ static int mv88e6xxx_g1_atu_op(struct mv88e6xxx_chip *chip, u16 fid, u16 op)
+ {
+       u16 val;
+@@ -127,6 +140,41 @@ int mv88e6xxx_g1_atu_get_next(struct mv88e6xxx_chip *chip, u16 fid)
+       return mv88e6xxx_g1_atu_op(chip, fid, MV88E6XXX_G1_ATU_OP_GET_NEXT_DB);
+ }
++static int mv88e6xxx_g1_atu_fid_read(struct mv88e6xxx_chip *chip, u16 *fid)
++{
++      u16 val = 0, upper = 0, op = 0;
++      int err = -EOPNOTSUPP;
++
++      if (mv88e6xxx_num_databases(chip) > 256) {
++              err = mv88e6xxx_g1_read(chip, MV88E6352_G1_ATU_FID, &val);
++              val &= 0xfff;
++              if (err)
++                      return err;
++      } else {
++              err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_OP, &op);
++              if (err)
++                      return err;
++              if (mv88e6xxx_num_databases(chip) > 64) {
++                      /* ATU DBNum[7:4] are located in ATU Control 15:12 */
++                      err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_CTL,
++                                              &upper);
++                      if (err)
++                              return err;
++
++                      upper = (upper >> 8) & 0x00f0;
++              } else if (mv88e6xxx_num_databases(chip) > 16) {
++                      /* ATU DBNum[5:4] are located in ATU Operation 9:8 */
++                      upper = (op >> 4) & 0x30;
++              }
++
++              /* ATU DBNum[3:0] are located in ATU Operation 3:0 */
++              val = (op & 0xf) | upper;
++      }
++      *fid = val;
++
++      return err;
++}
++
+ /* Offset 0x0C: ATU Data Register */
+ static int mv88e6xxx_g1_atu_data_read(struct mv88e6xxx_chip *chip,
+@@ -321,14 +369,12 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
+ {
+       struct mv88e6xxx_chip *chip = dev_id;
+       struct mv88e6xxx_atu_entry entry;
+-      int spid;
+-      int err;
+-      u16 val;
++      int err, spid;
++      u16 val, fid;
+       mv88e6xxx_reg_lock(chip);
+-      err = mv88e6xxx_g1_atu_op(chip, 0,
+-                                MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION);
++      err = mv88e6xxx_g1_read_atu_violation(chip);
+       if (err)
+               goto out;
+@@ -336,6 +382,10 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
+       if (err)
+               goto out;
++      err = mv88e6xxx_g1_atu_fid_read(chip, &fid);
++      if (err)
++              goto out;
++
+       err = mv88e6xxx_g1_atu_data_read(chip, &entry);
+       if (err)
+               goto out;
+@@ -354,22 +404,22 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
+       if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) {
+               dev_err_ratelimited(chip->dev,
+-                                  "ATU member violation for %pM portvec %x spid %d\n",
+-                                  entry.mac, entry.portvec, spid);
++                                  "ATU member violation for %pM fid %u portvec %x spid %d\n",
++                                  entry.mac, fid, entry.portvec, spid);
+               chip->ports[spid].atu_member_violation++;
+       }
+       if (val & MV88E6XXX_G1_ATU_OP_MISS_VIOLATION) {
+               dev_err_ratelimited(chip->dev,
+-                                  "ATU miss violation for %pM portvec %x spid %d\n",
+-                                  entry.mac, entry.portvec, spid);
++                                  "ATU miss violation for %pM fid %u portvec %x spid %d\n",
++                                  entry.mac, fid, entry.portvec, spid);
+               chip->ports[spid].atu_miss_violation++;
+       }
+       if (val & MV88E6XXX_G1_ATU_OP_FULL_VIOLATION) {
+               dev_err_ratelimited(chip->dev,
+-                                  "ATU full violation for %pM portvec %x spid %d\n",
+-                                  entry.mac, entry.portvec, spid);
++                                  "ATU full violation for %pM fid %u portvec %x spid %d\n",
++                                  entry.mac, fid, entry.portvec, spid);
+               chip->ports[spid].atu_full_violation++;
+       }
+       mv88e6xxx_reg_unlock(chip);
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-dsa-mv88e6xxx-replace-atu-violation-prints-with-.patch b/queue-5.4/net-dsa-mv88e6xxx-replace-atu-violation-prints-with-.patch
new file mode 100644 (file)
index 0000000..9840d1a
--- /dev/null
@@ -0,0 +1,186 @@
+From ddafb2d6f17c30ae9caa121a6f8982434da0ffb8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 19:28:16 +0200
+Subject: net: dsa: mv88e6xxx: replace ATU violation prints with trace points
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 8646384d80f3d3b4a66b3284dbbd8232d1b8799e ]
+
+In applications where the switch ports must perform 802.1X based
+authentication and are therefore locked, ATU violation interrupts are
+quite to be expected as part of normal operation. The problem is that
+they currently spam the kernel log, even if rate limited.
+
+Create a series of trace points, all derived from the same event class,
+which log these violations to the kernel's trace buffer, which is both
+much faster and much easier to ignore than printing to a serial console.
+
+New usage model:
+
+$ trace-cmd list | grep mv88e6xxx
+mv88e6xxx
+mv88e6xxx:mv88e6xxx_atu_full_violation
+mv88e6xxx:mv88e6xxx_atu_miss_violation
+mv88e6xxx:mv88e6xxx_atu_member_violation
+$ trace-cmd record -e mv88e6xxx sleep 10
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Saeed Mahameed <saeed@kernel.org>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 528876d867a2 ("net: dsa: mv88e6xxx: Fix out-of-bound access")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/Makefile      |  4 ++
+ drivers/net/dsa/mv88e6xxx/global1_atu.c | 19 +++----
+ drivers/net/dsa/mv88e6xxx/trace.c       |  6 +++
+ drivers/net/dsa/mv88e6xxx/trace.h       | 66 +++++++++++++++++++++++++
+ 4 files changed, 86 insertions(+), 9 deletions(-)
+ create mode 100644 drivers/net/dsa/mv88e6xxx/trace.c
+ create mode 100644 drivers/net/dsa/mv88e6xxx/trace.h
+
+diff --git a/drivers/net/dsa/mv88e6xxx/Makefile b/drivers/net/dsa/mv88e6xxx/Makefile
+index aa645ff86f641..2347d56c7155d 100644
+--- a/drivers/net/dsa/mv88e6xxx/Makefile
++++ b/drivers/net/dsa/mv88e6xxx/Makefile
+@@ -14,3 +14,7 @@ mv88e6xxx-objs += port_hidden.o
+ mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += ptp.o
+ mv88e6xxx-objs += serdes.o
+ mv88e6xxx-objs += smi.o
++mv88e6xxx-objs += trace.o
++
++# for tracing framework to find trace.h
++CFLAGS_trace.o := -I$(src)
+diff --git a/drivers/net/dsa/mv88e6xxx/global1_atu.c b/drivers/net/dsa/mv88e6xxx/global1_atu.c
+index 13ca45bf0f0bb..2b314b416256d 100644
+--- a/drivers/net/dsa/mv88e6xxx/global1_atu.c
++++ b/drivers/net/dsa/mv88e6xxx/global1_atu.c
+@@ -12,6 +12,7 @@
+ #include "chip.h"
+ #include "global1.h"
++#include "trace.h"
+ /* Offset 0x01: ATU FID Register */
+@@ -403,23 +404,23 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
+       }
+       if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) {
+-              dev_err_ratelimited(chip->dev,
+-                                  "ATU member violation for %pM fid %u portvec %x spid %d\n",
+-                                  entry.mac, fid, entry.portvec, spid);
++              trace_mv88e6xxx_atu_member_violation(chip->dev, spid,
++                                                   entry.portvec, entry.mac,
++                                                   fid);
+               chip->ports[spid].atu_member_violation++;
+       }
+       if (val & MV88E6XXX_G1_ATU_OP_MISS_VIOLATION) {
+-              dev_err_ratelimited(chip->dev,
+-                                  "ATU miss violation for %pM fid %u portvec %x spid %d\n",
+-                                  entry.mac, fid, entry.portvec, spid);
++              trace_mv88e6xxx_atu_miss_violation(chip->dev, spid,
++                                                 entry.portvec, entry.mac,
++                                                 fid);
+               chip->ports[spid].atu_miss_violation++;
+       }
+       if (val & MV88E6XXX_G1_ATU_OP_FULL_VIOLATION) {
+-              dev_err_ratelimited(chip->dev,
+-                                  "ATU full violation for %pM fid %u portvec %x spid %d\n",
+-                                  entry.mac, fid, entry.portvec, spid);
++              trace_mv88e6xxx_atu_full_violation(chip->dev, spid,
++                                                 entry.portvec, entry.mac,
++                                                 fid);
+               chip->ports[spid].atu_full_violation++;
+       }
+       mv88e6xxx_reg_unlock(chip);
+diff --git a/drivers/net/dsa/mv88e6xxx/trace.c b/drivers/net/dsa/mv88e6xxx/trace.c
+new file mode 100644
+index 0000000000000..7833cb50ca5d7
+--- /dev/null
++++ b/drivers/net/dsa/mv88e6xxx/trace.c
+@@ -0,0 +1,6 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/* Copyright 2022 NXP
++ */
++
++#define CREATE_TRACE_POINTS
++#include "trace.h"
+diff --git a/drivers/net/dsa/mv88e6xxx/trace.h b/drivers/net/dsa/mv88e6xxx/trace.h
+new file mode 100644
+index 0000000000000..d9ab5c8dee55d
+--- /dev/null
++++ b/drivers/net/dsa/mv88e6xxx/trace.h
+@@ -0,0 +1,66 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later */
++/* Copyright 2022 NXP
++ */
++
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM  mv88e6xxx
++
++#if !defined(_MV88E6XXX_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
++#define _MV88E6XXX_TRACE_H
++
++#include <linux/device.h>
++#include <linux/if_ether.h>
++#include <linux/tracepoint.h>
++
++DECLARE_EVENT_CLASS(mv88e6xxx_atu_violation,
++
++      TP_PROTO(const struct device *dev, int spid, u16 portvec,
++               const unsigned char *addr, u16 fid),
++
++      TP_ARGS(dev, spid, portvec, addr, fid),
++
++      TP_STRUCT__entry(
++              __string(name, dev_name(dev))
++              __field(int, spid)
++              __field(u16, portvec)
++              __array(unsigned char, addr, ETH_ALEN)
++              __field(u16, fid)
++      ),
++
++      TP_fast_assign(
++              __assign_str(name, dev_name(dev));
++              __entry->spid = spid;
++              __entry->portvec = portvec;
++              memcpy(__entry->addr, addr, ETH_ALEN);
++              __entry->fid = fid;
++      ),
++
++      TP_printk("dev %s spid %d portvec 0x%x addr %pM fid %u",
++                __get_str(name), __entry->spid, __entry->portvec,
++                __entry->addr, __entry->fid)
++);
++
++DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_member_violation,
++           TP_PROTO(const struct device *dev, int spid, u16 portvec,
++                    const unsigned char *addr, u16 fid),
++           TP_ARGS(dev, spid, portvec, addr, fid));
++
++DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_miss_violation,
++           TP_PROTO(const struct device *dev, int spid, u16 portvec,
++                    const unsigned char *addr, u16 fid),
++           TP_ARGS(dev, spid, portvec, addr, fid));
++
++DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_full_violation,
++           TP_PROTO(const struct device *dev, int spid, u16 portvec,
++                    const unsigned char *addr, u16 fid),
++           TP_ARGS(dev, spid, portvec, addr, fid));
++
++#endif /* _MV88E6XXX_TRACE_H */
++
++/* We don't want to use include/trace/events */
++#undef TRACE_INCLUDE_PATH
++#define TRACE_INCLUDE_PATH .
++#undef TRACE_INCLUDE_FILE
++#define TRACE_INCLUDE_FILE    trace
++/* This part must be outside protection */
++#include <trace/define_trace.h>
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-xilinx-axienet-always-disable-promiscuous-mode.patch b/queue-5.4/net-xilinx-axienet-always-disable-promiscuous-mode.patch
new file mode 100644 (file)
index 0000000..84ae1b2
--- /dev/null
@@ -0,0 +1,42 @@
+From ed4fb025a5a4a211e115c61289c751f40281ef2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Aug 2024 11:40:55 -0400
+Subject: net: xilinx: axienet: Always disable promiscuous mode
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+[ Upstream commit 4ae738dfef2c0323752ab81786e2d298c9939321 ]
+
+If promiscuous mode is disabled when there are fewer than four multicast
+addresses, then it will not be reflected in the hardware. Fix this by
+always clearing the promiscuous mode flag even when we program multicast
+addresses.
+
+Fixes: 8a3b7a252dca ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20240822154059.1066595-2-sean.anderson@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index 1156719210cdb..80bb6b85bd441 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -427,6 +427,10 @@ static void axienet_set_multicast_list(struct net_device *ndev)
+       } else if (!netdev_mc_empty(ndev)) {
+               struct netdev_hw_addr *ha;
++              reg = axienet_ior(lp, XAE_FMI_OFFSET);
++              reg &= ~XAE_FMI_PM_MASK;
++              axienet_iow(lp, XAE_FMI_OFFSET, reg);
++
+               i = 0;
+               netdev_for_each_mc_addr(ha, ndev) {
+                       if (i >= XAE_MULTICAST_CAM_TABLE_NUM)
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-xilinx-axienet-fix-dangling-multicast-addresses.patch b/queue-5.4/net-xilinx-axienet-fix-dangling-multicast-addresses.patch
new file mode 100644 (file)
index 0000000..178b3c9
--- /dev/null
@@ -0,0 +1,94 @@
+From 4fb9074230809ceec3b185c6d37db545544c89a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Aug 2024 11:40:56 -0400
+Subject: net: xilinx: axienet: Fix dangling multicast addresses
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+[ Upstream commit 797a68c9de0f5a5447baf4bd3bb9c10a3993435b ]
+
+If a multicast address is removed but there are still some multicast
+addresses, that address would remain programmed into the frame filter.
+Fix this by explicitly setting the enable bit for each filter.
+
+Fixes: 8a3b7a252dca ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20240822154059.1066595-3-sean.anderson@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xilinx/xilinx_axienet.h  |  1 +
+ .../net/ethernet/xilinx/xilinx_axienet_main.c | 21 ++++++++-----------
+ 2 files changed, 10 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+index bf1a19a00adc6..c43d437f22bdf 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+@@ -169,6 +169,7 @@
+ #define XAE_UAW0_OFFSET               0x00000700 /* Unicast address word 0 */
+ #define XAE_UAW1_OFFSET               0x00000704 /* Unicast address word 1 */
+ #define XAE_FMI_OFFSET                0x00000708 /* Frame Filter Control */
++#define XAE_FFE_OFFSET                0x0000070C /* Frame Filter Enable */
+ #define XAE_AF0_OFFSET                0x00000710 /* Address Filter 0 */
+ #define XAE_AF1_OFFSET                0x00000714 /* Address Filter 1 */
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index 80bb6b85bd441..2aacc077ee2bc 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -409,7 +409,7 @@ static int netdev_set_mac_address(struct net_device *ndev, void *p)
+  */
+ static void axienet_set_multicast_list(struct net_device *ndev)
+ {
+-      int i;
++      int i = 0;
+       u32 reg, af0reg, af1reg;
+       struct axienet_local *lp = netdev_priv(ndev);
+@@ -431,7 +431,6 @@ static void axienet_set_multicast_list(struct net_device *ndev)
+               reg &= ~XAE_FMI_PM_MASK;
+               axienet_iow(lp, XAE_FMI_OFFSET, reg);
+-              i = 0;
+               netdev_for_each_mc_addr(ha, ndev) {
+                       if (i >= XAE_MULTICAST_CAM_TABLE_NUM)
+                               break;
+@@ -450,6 +449,7 @@ static void axienet_set_multicast_list(struct net_device *ndev)
+                       axienet_iow(lp, XAE_FMI_OFFSET, reg);
+                       axienet_iow(lp, XAE_AF0_OFFSET, af0reg);
+                       axienet_iow(lp, XAE_AF1_OFFSET, af1reg);
++                      axienet_iow(lp, XAE_FFE_OFFSET, 1);
+                       i++;
+               }
+       } else {
+@@ -457,18 +457,15 @@ static void axienet_set_multicast_list(struct net_device *ndev)
+               reg &= ~XAE_FMI_PM_MASK;
+               axienet_iow(lp, XAE_FMI_OFFSET, reg);
+-
+-              for (i = 0; i < XAE_MULTICAST_CAM_TABLE_NUM; i++) {
+-                      reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00;
+-                      reg |= i;
+-
+-                      axienet_iow(lp, XAE_FMI_OFFSET, reg);
+-                      axienet_iow(lp, XAE_AF0_OFFSET, 0);
+-                      axienet_iow(lp, XAE_AF1_OFFSET, 0);
+-              }
+-
+               dev_info(&ndev->dev, "Promiscuous mode disabled.\n");
+       }
++
++      for (; i < XAE_MULTICAST_CAM_TABLE_NUM; i++) {
++              reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00;
++              reg |= i;
++              axienet_iow(lp, XAE_FMI_OFFSET, reg);
++              axienet_iow(lp, XAE_FFE_OFFSET, 0);
++      }
+ }
+ /**
+-- 
+2.43.0
+
diff --git a/queue-5.4/netem-fix-return-value-if-duplicate-enqueue-fails.patch b/queue-5.4/netem-fix-return-value-if-duplicate-enqueue-fails.patch
new file mode 100644 (file)
index 0000000..049b87b
--- /dev/null
@@ -0,0 +1,138 @@
+From 141ca204dec0e3e6ed56ff580ba002837903ac6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Aug 2024 10:56:45 -0700
+Subject: netem: fix return value if duplicate enqueue fails
+
+From: Stephen Hemminger <stephen@networkplumber.org>
+
+[ Upstream commit c07ff8592d57ed258afee5a5e04991a48dbaf382 ]
+
+There is a bug in netem_enqueue() introduced by
+commit 5845f706388a ("net: netem: fix skb length BUG_ON in __skb_to_sgvec")
+that can lead to a use-after-free.
+
+This commit made netem_enqueue() always return NET_XMIT_SUCCESS
+when a packet is duplicated, which can cause the parent qdisc's q.qlen
+to be mistakenly incremented. When this happens qlen_notify() may be
+skipped on the parent during destruction, leaving a dangling pointer
+for some classful qdiscs like DRR.
+
+There are two ways for the bug happen:
+
+- If the duplicated packet is dropped by rootq->enqueue() and then
+  the original packet is also dropped.
+- If rootq->enqueue() sends the duplicated packet to a different qdisc
+  and the original packet is dropped.
+
+In both cases NET_XMIT_SUCCESS is returned even though no packets
+are enqueued at the netem qdisc.
+
+The fix is to defer the enqueue of the duplicate packet until after
+the original packet has been guaranteed to return NET_XMIT_SUCCESS.
+
+Fixes: 5845f706388a ("net: netem: fix skb length BUG_ON in __skb_to_sgvec")
+Reported-by: Budimir Markovic <markovicbudimir@gmail.com>
+Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20240819175753.5151-1-stephen@networkplumber.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_netem.c | 47 ++++++++++++++++++++++++++-----------------
+ 1 file changed, 29 insertions(+), 18 deletions(-)
+
+diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
+index 265a02b6ad099..591ca93e2a01d 100644
+--- a/net/sched/sch_netem.c
++++ b/net/sched/sch_netem.c
+@@ -437,12 +437,10 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+       struct netem_sched_data *q = qdisc_priv(sch);
+       /* We don't fill cb now as skb_unshare() may invalidate it */
+       struct netem_skb_cb *cb;
+-      struct sk_buff *skb2;
++      struct sk_buff *skb2 = NULL;
+       struct sk_buff *segs = NULL;
+       unsigned int prev_len = qdisc_pkt_len(skb);
+       int count = 1;
+-      int rc = NET_XMIT_SUCCESS;
+-      int rc_drop = NET_XMIT_DROP;
+       /* Do not fool qdisc_drop_all() */
+       skb->prev = NULL;
+@@ -471,19 +469,11 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+               skb_orphan_partial(skb);
+       /*
+-       * If we need to duplicate packet, then re-insert at top of the
+-       * qdisc tree, since parent queuer expects that only one
+-       * skb will be queued.
++       * If we need to duplicate packet, then clone it before
++       * original is modified.
+        */
+-      if (count > 1 && (skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) {
+-              struct Qdisc *rootq = qdisc_root_bh(sch);
+-              u32 dupsave = q->duplicate; /* prevent duplicating a dup... */
+-
+-              q->duplicate = 0;
+-              rootq->enqueue(skb2, rootq, to_free);
+-              q->duplicate = dupsave;
+-              rc_drop = NET_XMIT_SUCCESS;
+-      }
++      if (count > 1)
++              skb2 = skb_clone(skb, GFP_ATOMIC);
+       /*
+        * Randomized packet corruption.
+@@ -495,7 +485,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+               if (skb_is_gso(skb)) {
+                       skb = netem_segment(skb, sch, to_free);
+                       if (!skb)
+-                              return rc_drop;
++                              goto finish_segs;
++
+                       segs = skb->next;
+                       skb_mark_not_on_list(skb);
+                       qdisc_skb_cb(skb)->pkt_len = skb->len;
+@@ -521,7 +512,24 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+               /* re-link segs, so that qdisc_drop_all() frees them all */
+               skb->next = segs;
+               qdisc_drop_all(skb, sch, to_free);
+-              return rc_drop;
++              if (skb2)
++                      __qdisc_drop(skb2, to_free);
++              return NET_XMIT_DROP;
++      }
++
++      /*
++       * If doing duplication then re-insert at top of the
++       * qdisc tree, since parent queuer expects that only one
++       * skb will be queued.
++       */
++      if (skb2) {
++              struct Qdisc *rootq = qdisc_root_bh(sch);
++              u32 dupsave = q->duplicate; /* prevent duplicating a dup... */
++
++              q->duplicate = 0;
++              rootq->enqueue(skb2, rootq, to_free);
++              q->duplicate = dupsave;
++              skb2 = NULL;
+       }
+       qdisc_qstats_backlog_inc(sch, skb);
+@@ -592,9 +600,12 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+       }
+ finish_segs:
++      if (skb2)
++              __qdisc_drop(skb2, to_free);
++
+       if (segs) {
+               unsigned int len, last_len;
+-              int nb;
++              int rc, nb;
+               len = skb ? skb->len : 0;
+               nb = skb ? 1 : 0;
+-- 
+2.43.0
+
diff --git a/queue-5.4/netfilter-nft_counter-synchronize-nft_counter_reset-.patch b/queue-5.4/netfilter-nft_counter-synchronize-nft_counter_reset-.patch
new file mode 100644 (file)
index 0000000..41b7a5e
--- /dev/null
@@ -0,0 +1,50 @@
+From 1384507cd1c1ae9ce8ae829a36111b5fcbed0094 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Aug 2024 09:54:31 +0200
+Subject: netfilter: nft_counter: Synchronize nft_counter_reset() against
+ reader.
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+[ Upstream commit a0b39e2dc7017ac667b70bdeee5293e410fab2fb ]
+
+nft_counter_reset() resets the counter by subtracting the previously
+retrieved value from the counter. This is a write operation on the
+counter and as such it requires to be performed with a write sequence of
+nft_counter_seq to serialize against its possible reader.
+
+Update the packets/ bytes within write-sequence of nft_counter_seq.
+
+Fixes: d84701ecbcd6a ("netfilter: nft_counter: rework atomic dump and reset")
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_counter.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c
+index f6d4d0fa23a62..bf829fabf2785 100644
+--- a/net/netfilter/nft_counter.c
++++ b/net/netfilter/nft_counter.c
+@@ -105,11 +105,16 @@ static void nft_counter_reset(struct nft_counter_percpu_priv *priv,
+                             struct nft_counter *total)
+ {
+       struct nft_counter *this_cpu;
++      seqcount_t *myseq;
+       local_bh_disable();
+       this_cpu = this_cpu_ptr(priv->counter);
++      myseq = this_cpu_ptr(&nft_counter_seq);
++
++      write_seqcount_begin(myseq);
+       this_cpu->packets -= total->packets;
+       this_cpu->bytes -= total->bytes;
++      write_seqcount_end(myseq);
+       local_bh_enable();
+ }
+-- 
+2.43.0
+
index 31cdfd5d37f8da392387ddb720bc690c71b1b223..ca7baa91f1e1ed7bf1fea1252ad9a27c4843b898 100644 (file)
@@ -79,3 +79,18 @@ media-solo6x10-replace-max-a-min-b-c-by-clamp-b-a-c.patch
 dm-mpath-pass-io-start-time-to-path-selector.patch
 dm-do-not-use-waitqueue-for-request-based-dm.patch
 dm-suspend-return-erestartsys-instead-of-eintr.patch
+bluetooth-make-use-of-__check_timeout-on-hci_sched_l.patch
+bluetooth-hci_core-fix-not-handling-link-timeouts-pr.patch
+bluetooth-hci_core-fix-le-quote-calculation.patch
+tc-testing-don-t-access-non-existent-variable-on-exc.patch
+kcm-serialise-kcm_sendmsg-for-the-same-socket.patch
+netfilter-nft_counter-synchronize-nft_counter_reset-.patch
+net-dsa-mv88e6xxx-global2-expose-atu-stats-register.patch
+net-dsa-mv88e6xxx-global1_atu-add-helper-for-get-nex.patch
+net-dsa-mv88e6xxx-read-fid-when-handling-atu-violati.patch
+net-dsa-mv88e6xxx-replace-atu-violation-prints-with-.patch
+net-dsa-mv88e6xxx-fix-out-of-bound-access.patch
+netem-fix-return-value-if-duplicate-enqueue-fails.patch
+ipv6-prevent-uaf-in-ip6_send_skb.patch
+net-xilinx-axienet-always-disable-promiscuous-mode.patch
+net-xilinx-axienet-fix-dangling-multicast-addresses.patch
diff --git a/queue-5.4/tc-testing-don-t-access-non-existent-variable-on-exc.patch b/queue-5.4/tc-testing-don-t-access-non-existent-variable-on-exc.patch
new file mode 100644 (file)
index 0000000..d022fe2
--- /dev/null
@@ -0,0 +1,60 @@
+From 3d1a569663cdee596dddfa6f36bf5275f9924080 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Aug 2024 16:37:13 +0100
+Subject: tc-testing: don't access non-existent variable on exception
+
+From: Simon Horman <horms@kernel.org>
+
+[ Upstream commit a0c9fe5eecc97680323ee83780ea3eaf440ba1b7 ]
+
+Since commit 255c1c7279ab ("tc-testing: Allow test cases to be skipped")
+the variable test_ordinal doesn't exist in call_pre_case().
+So it should not be accessed when an exception occurs.
+
+This resolves the following splat:
+
+  ...
+  During handling of the above exception, another exception occurred:
+
+  Traceback (most recent call last):
+    File ".../tdc.py", line 1028, in <module>
+      main()
+    File ".../tdc.py", line 1022, in main
+      set_operation_mode(pm, parser, args, remaining)
+    File ".../tdc.py", line 966, in set_operation_mode
+      catresults = test_runner_serial(pm, args, alltests)
+    File ".../tdc.py", line 642, in test_runner_serial
+      (index, tsr) = test_runner(pm, args, alltests)
+    File ".../tdc.py", line 536, in test_runner
+      res = run_one_test(pm, args, index, tidx)
+    File ".../tdc.py", line 419, in run_one_test
+      pm.call_pre_case(tidx)
+    File ".../tdc.py", line 146, in call_pre_case
+      print('test_ordinal is {}'.format(test_ordinal))
+  NameError: name 'test_ordinal' is not defined
+
+Fixes: 255c1c7279ab ("tc-testing: Allow test cases to be skipped")
+Signed-off-by: Simon Horman <horms@kernel.org>
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20240815-tdc-test-ordinal-v1-1-0255c122a427@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/tc-testing/tdc.py | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/tools/testing/selftests/tc-testing/tdc.py b/tools/testing/selftests/tc-testing/tdc.py
+index e566c70e64a19..81f76a5d12ac6 100755
+--- a/tools/testing/selftests/tc-testing/tdc.py
++++ b/tools/testing/selftests/tc-testing/tdc.py
+@@ -129,7 +129,6 @@ class PluginMgr:
+             except Exception as ee:
+                 print('exception {} in call to pre_case for {} plugin'.
+                       format(ee, pgn_inst.__class__))
+-                print('test_ordinal is {}'.format(test_ordinal))
+                 print('testid is {}'.format(caseinfo['id']))
+                 raise
+-- 
+2.43.0
+