From 835fd1f5223b00cf62705f2e5e84666ef36727ae Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Fri, 8 Dec 2023 21:37:00 -0500 Subject: [PATCH] Fixes for 4.19 Signed-off-by: Sasha Levin --- ...-support-for-multiple-sohard-arcnet-.patch | 216 ++++++++++ ...vsc-rndis_filter-needs-to-select-nls.patch | 44 ++ ...avoid-skb_pull-failure-in-ipgre_xmit.patch | 58 +++ ...fix-potential-null-deref-in-fib6_add.patch | 79 ++++ ...t-arcnet-com20020-fix-error-handling.patch | 137 ++++++ .../net-arcnet-fix-reset-flag-handling.patch | 315 ++++++++++++++ ...-dev-add-extack-argument-to-dev_open.patch | 407 ++++++++++++++++++ ...net-hns-fix-fake-link-up-on-xge-port.patch | 74 ++++ ...wner-add-supplementary-groups-option.patch | 81 ++++ ...er-fix-for-unsafe-access-of-sk-sk_so.patch | 71 +++ queue-4.19/series | 11 + ...ot-accept-ack-of-bytes-we-never-sent.patch | 106 +++++ 12 files changed, 1599 insertions(+) create mode 100644 queue-4.19/arcnet-restoring-support-for-multiple-sohard-arcnet-.patch create mode 100644 queue-4.19/hv_netvsc-rndis_filter-needs-to-select-nls.patch create mode 100644 queue-4.19/ipv4-ip_gre-avoid-skb_pull-failure-in-ipgre_xmit.patch create mode 100644 queue-4.19/ipv6-fix-potential-null-deref-in-fib6_add.patch create mode 100644 queue-4.19/net-arcnet-com20020-fix-error-handling.patch create mode 100644 queue-4.19/net-arcnet-fix-reset-flag-handling.patch create mode 100644 queue-4.19/net-core-dev-add-extack-argument-to-dev_open.patch create mode 100644 queue-4.19/net-hns-fix-fake-link-up-on-xge-port.patch create mode 100644 queue-4.19/netfilter-xt_owner-add-supplementary-groups-option.patch create mode 100644 queue-4.19/netfilter-xt_owner-fix-for-unsafe-access-of-sk-sk_so.patch create mode 100644 queue-4.19/tcp-do-not-accept-ack-of-bytes-we-never-sent.patch diff --git a/queue-4.19/arcnet-restoring-support-for-multiple-sohard-arcnet-.patch b/queue-4.19/arcnet-restoring-support-for-multiple-sohard-arcnet-.patch new file mode 100644 index 00000000000..c59fb506f05 --- /dev/null +++ b/queue-4.19/arcnet-restoring-support-for-multiple-sohard-arcnet-.patch @@ -0,0 +1,216 @@ +From 4c5b13d0956757d4493dabadaa6ea11310885972 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Nov 2023 12:35:03 +0100 +Subject: arcnet: restoring support for multiple Sohard Arcnet cards + +From: Thomas Reichinger + +[ Upstream commit 6b17a597fc2f13aaaa0a2780eb7edb9ae7ac9aea ] + +Probe of Sohard Arcnet cards fails, +if 2 or more cards are installed in a system. +See kernel log: +[ 2.759203] arcnet: arcnet loaded +[ 2.763648] arcnet:com20020: COM20020 chipset support (by David Woodhouse et al.) +[ 2.770585] arcnet:com20020_pci: COM20020 PCI support +[ 2.772295] com20020 0000:02:00.0: enabling device (0000 -> 0003) +[ 2.772354] (unnamed net_device) (uninitialized): PLX-PCI Controls +... +[ 3.071301] com20020 0000:02:00.0 arc0-0 (uninitialized): PCI COM20020: station FFh found at F080h, IRQ 101. +[ 3.071305] com20020 0000:02:00.0 arc0-0 (uninitialized): Using CKP 64 - data rate 2.5 Mb/s +[ 3.071534] com20020 0000:07:00.0: enabling device (0000 -> 0003) +[ 3.071581] (unnamed net_device) (uninitialized): PLX-PCI Controls +... +[ 3.369501] com20020 0000:07:00.0: Led pci:green:tx:0-0 renamed to pci:green:tx:0-0_1 due to name collision +[ 3.369535] com20020 0000:07:00.0: Led pci:red:recon:0-0 renamed to pci:red:recon:0-0_1 due to name collision +[ 3.370586] com20020 0000:07:00.0 arc0-0 (uninitialized): PCI COM20020: station E1h found at C000h, IRQ 35. +[ 3.370589] com20020 0000:07:00.0 arc0-0 (uninitialized): Using CKP 64 - data rate 2.5 Mb/s +[ 3.370608] com20020: probe of 0000:07:00.0 failed with error -5 + +commit 5ef216c1f848 ("arcnet: com20020-pci: add rotary index support") +changes the device name of all COM20020 based PCI cards, +even if only some cards support this: + snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i); + +The error happens because all Sohard Arcnet cards would be called arc0-0, +since the Sohard Arcnet cards don't have a PLX rotary coder. +I.e. EAE Arcnet cards have a PLX rotary coder, +which sets the first decimal, ensuring unique devices names. + +This patch adds two new card feature flags to indicate +which cards support LEDs and the PLX rotary coder. +For EAE based cards the names still depend on the PLX rotary coder +(untested, since missing EAE hardware). +For Sohard based cards, this patch will result in devices +being called arc0, arc1, ... (tested). + +Signed-off-by: Thomas Reichinger +Fixes: 5ef216c1f848 ("arcnet: com20020-pci: add rotary index support") +Link: https://lore.kernel.org/r/20231130113503.6812-1-thomas.reichinger@sohard.de +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/arcnet/arcdevice.h | 2 + + drivers/net/arcnet/com20020-pci.c | 89 ++++++++++++++++--------------- + 2 files changed, 48 insertions(+), 43 deletions(-) + +diff --git a/drivers/net/arcnet/arcdevice.h b/drivers/net/arcnet/arcdevice.h +index 1ad5e4a03d23e..c72ad5e2ac5f0 100644 +--- a/drivers/net/arcnet/arcdevice.h ++++ b/drivers/net/arcnet/arcdevice.h +@@ -191,6 +191,8 @@ do { \ + #define ARC_IS_5MBIT 1 /* card default speed is 5MBit */ + #define ARC_CAN_10MBIT 2 /* card uses COM20022, supporting 10MBit, + but default is 2.5MBit. */ ++#define ARC_HAS_LED 4 /* card has software controlled LEDs */ ++#define ARC_HAS_ROTARY 8 /* card has rotary encoder */ + + /* information needed to define an encapsulation driver */ + struct ArcProto { +diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c +index 28dccbc0e8d8f..9d9e4200064f9 100644 +--- a/drivers/net/arcnet/com20020-pci.c ++++ b/drivers/net/arcnet/com20020-pci.c +@@ -213,12 +213,13 @@ static int com20020pci_probe(struct pci_dev *pdev, + if (!strncmp(ci->name, "EAE PLX-PCI FB2", 15)) + lp->backplane = 1; + +- /* Get the dev_id from the PLX rotary coder */ +- if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15)) +- dev_id_mask = 0x3; +- dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask; +- +- snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i); ++ if (ci->flags & ARC_HAS_ROTARY) { ++ /* Get the dev_id from the PLX rotary coder */ ++ if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15)) ++ dev_id_mask = 0x3; ++ dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask; ++ snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i); ++ } + + if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) { + pr_err("IO address %Xh is empty!\n", ioaddr); +@@ -230,6 +231,10 @@ static int com20020pci_probe(struct pci_dev *pdev, + goto err_free_arcdev; + } + ++ ret = com20020_found(dev, IRQF_SHARED); ++ if (ret) ++ goto err_free_arcdev; ++ + card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev), + GFP_KERNEL); + if (!card) { +@@ -239,41 +244,39 @@ static int com20020pci_probe(struct pci_dev *pdev, + + card->index = i; + card->pci_priv = priv; +- card->tx_led.brightness_set = led_tx_set; +- card->tx_led.default_trigger = devm_kasprintf(&pdev->dev, +- GFP_KERNEL, "arc%d-%d-tx", +- dev->dev_id, i); +- card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, +- "pci:green:tx:%d-%d", +- dev->dev_id, i); +- +- card->tx_led.dev = &dev->dev; +- card->recon_led.brightness_set = led_recon_set; +- card->recon_led.default_trigger = devm_kasprintf(&pdev->dev, +- GFP_KERNEL, "arc%d-%d-recon", +- dev->dev_id, i); +- card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, +- "pci:red:recon:%d-%d", +- dev->dev_id, i); +- card->recon_led.dev = &dev->dev; +- card->dev = dev; +- +- ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); +- if (ret) +- goto err_free_arcdev; + +- ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); +- if (ret) +- goto err_free_arcdev; +- +- dev_set_drvdata(&dev->dev, card); +- +- ret = com20020_found(dev, IRQF_SHARED); +- if (ret) +- goto err_free_arcdev; +- +- devm_arcnet_led_init(dev, dev->dev_id, i); ++ if (ci->flags & ARC_HAS_LED) { ++ card->tx_led.brightness_set = led_tx_set; ++ card->tx_led.default_trigger = devm_kasprintf(&pdev->dev, ++ GFP_KERNEL, "arc%d-%d-tx", ++ dev->dev_id, i); ++ card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, ++ "pci:green:tx:%d-%d", ++ dev->dev_id, i); ++ ++ card->tx_led.dev = &dev->dev; ++ card->recon_led.brightness_set = led_recon_set; ++ card->recon_led.default_trigger = devm_kasprintf(&pdev->dev, ++ GFP_KERNEL, "arc%d-%d-recon", ++ dev->dev_id, i); ++ card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, ++ "pci:red:recon:%d-%d", ++ dev->dev_id, i); ++ card->recon_led.dev = &dev->dev; ++ ++ ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); ++ if (ret) ++ goto err_free_arcdev; ++ ++ ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); ++ if (ret) ++ goto err_free_arcdev; ++ ++ dev_set_drvdata(&dev->dev, card); ++ devm_arcnet_led_init(dev, dev->dev_id, i); ++ } + ++ card->dev = dev; + list_add(&card->list, &priv->list_dev); + continue; + +@@ -329,7 +332,7 @@ static struct com20020_pci_card_info card_info_5mbit = { + }; + + static struct com20020_pci_card_info card_info_sohard = { +- .name = "PLX-PCI", ++ .name = "SOHARD SH ARC-PCI", + .devcount = 1, + /* SOHARD needs PCI base addr 4 */ + .chan_map_tbl = { +@@ -364,7 +367,7 @@ static struct com20020_pci_card_info card_info_eae_arc1 = { + }, + }, + .rotary = 0x0, +- .flags = ARC_CAN_10MBIT, ++ .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, + }; + + static struct com20020_pci_card_info card_info_eae_ma1 = { +@@ -396,7 +399,7 @@ static struct com20020_pci_card_info card_info_eae_ma1 = { + }, + }, + .rotary = 0x0, +- .flags = ARC_CAN_10MBIT, ++ .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, + }; + + static struct com20020_pci_card_info card_info_eae_fb2 = { +@@ -421,7 +424,7 @@ static struct com20020_pci_card_info card_info_eae_fb2 = { + }, + }, + .rotary = 0x0, +- .flags = ARC_CAN_10MBIT, ++ .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, + }; + + static const struct pci_device_id com20020pci_id_table[] = { +-- +2.42.0 + diff --git a/queue-4.19/hv_netvsc-rndis_filter-needs-to-select-nls.patch b/queue-4.19/hv_netvsc-rndis_filter-needs-to-select-nls.patch new file mode 100644 index 00000000000..78d79b41bac --- /dev/null +++ b/queue-4.19/hv_netvsc-rndis_filter-needs-to-select-nls.patch @@ -0,0 +1,44 @@ +From faceb68b4101127e78384ed1d374de76f0772082 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Nov 2023 21:58:53 -0800 +Subject: hv_netvsc: rndis_filter needs to select NLS + +From: Randy Dunlap + +[ Upstream commit 6c89f49964375c904cea33c0247467873f4daf2c ] + +rndis_filter uses utf8s_to_utf16s() which is provided by setting +NLS, so select NLS to fix the build error: + +ERROR: modpost: "utf8s_to_utf16s" [drivers/net/hyperv/hv_netvsc.ko] undefined! + +Fixes: 1ce09e899d28 ("hyperv: Add support for setting MAC from within guests") +Signed-off-by: Randy Dunlap +Cc: Haiyang Zhang +Cc: K. Y. Srinivasan +Cc: Wei Liu +Cc: Dexuan Cui +Reviewed-by: Simon Horman +Tested-by: Simon Horman # build-tested +Reviewed-by: Michael Kelley +Link: https://lore.kernel.org/r/20231130055853.19069-1-rdunlap@infradead.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/hyperv/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/hyperv/Kconfig b/drivers/net/hyperv/Kconfig +index 0765d5f61714e..386658ce1297a 100644 +--- a/drivers/net/hyperv/Kconfig ++++ b/drivers/net/hyperv/Kconfig +@@ -2,5 +2,6 @@ config HYPERV_NET + tristate "Microsoft Hyper-V virtual network driver" + depends on HYPERV + select UCS2_STRING ++ select NLS + help + Select this option to enable the Hyper-V virtual network driver. +-- +2.42.0 + diff --git a/queue-4.19/ipv4-ip_gre-avoid-skb_pull-failure-in-ipgre_xmit.patch b/queue-4.19/ipv4-ip_gre-avoid-skb_pull-failure-in-ipgre_xmit.patch new file mode 100644 index 00000000000..603fbbc308e --- /dev/null +++ b/queue-4.19/ipv4-ip_gre-avoid-skb_pull-failure-in-ipgre_xmit.patch @@ -0,0 +1,58 @@ +From 51505d998222cbd905de92c4fdfba9ecc1825d3b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 3 Dec 2023 01:14:41 +0900 +Subject: ipv4: ip_gre: Avoid skb_pull() failure in ipgre_xmit() + +From: Shigeru Yoshida + +[ Upstream commit 80d875cfc9d3711a029f234ef7d680db79e8fa4b ] + +In ipgre_xmit(), skb_pull() may fail even if pskb_inet_may_pull() returns +true. For example, applications can use PF_PACKET to create a malformed +packet with no IP header. This type of packet causes a problem such as +uninit-value access. + +This patch ensures that skb_pull() can pull the required size by checking +the skb with pskb_network_may_pull() before skb_pull(). + +Fixes: c54419321455 ("GRE: Refactor GRE tunneling code.") +Signed-off-by: Shigeru Yoshida +Reviewed-by: Eric Dumazet +Reviewed-by: Suman Ghosh +Link: https://lore.kernel.org/r/20231202161441.221135-1-syoshida@redhat.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/ipv4/ip_gre.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c +index e16373640f4c2..38c8db78cda19 100644 +--- a/net/ipv4/ip_gre.c ++++ b/net/ipv4/ip_gre.c +@@ -683,15 +683,18 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, + } + + if (dev->header_ops) { ++ int pull_len = tunnel->hlen + sizeof(struct iphdr); ++ + if (skb_cow_head(skb, 0)) + goto free_skb; + + tnl_params = (const struct iphdr *)skb->data; + +- /* Pull skb since ip_tunnel_xmit() needs skb->data pointing +- * to gre header. +- */ +- skb_pull(skb, tunnel->hlen + sizeof(struct iphdr)); ++ if (!pskb_network_may_pull(skb, pull_len)) ++ goto free_skb; ++ ++ /* ip_tunnel_xmit() needs skb->data pointing to gre header. */ ++ skb_pull(skb, pull_len); + skb_reset_mac_header(skb); + + if (skb->ip_summed == CHECKSUM_PARTIAL && +-- +2.42.0 + diff --git a/queue-4.19/ipv6-fix-potential-null-deref-in-fib6_add.patch b/queue-4.19/ipv6-fix-potential-null-deref-in-fib6_add.patch new file mode 100644 index 00000000000..9df5b85a901 --- /dev/null +++ b/queue-4.19/ipv6-fix-potential-null-deref-in-fib6_add.patch @@ -0,0 +1,79 @@ +From 41cb79f7ddb5fe961eb4aa680b2c0d75c7b3cded Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Nov 2023 16:06:30 +0000 +Subject: ipv6: fix potential NULL deref in fib6_add() + +From: Eric Dumazet + +[ Upstream commit 75475bb51e78a3f54ad2f69380f2a1c985e85f2d ] + +If fib6_find_prefix() returns NULL, we should silently fallback +using fib6_null_entry regardless of RT6_DEBUG value. + +syzbot reported: + +WARNING: CPU: 0 PID: 5477 at net/ipv6/ip6_fib.c:1516 fib6_add+0x310d/0x3fa0 net/ipv6/ip6_fib.c:1516 +Modules linked in: +CPU: 0 PID: 5477 Comm: syz-executor.0 Not tainted 6.7.0-rc2-syzkaller-00029-g9b6de136b5f0 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/10/2023 +RIP: 0010:fib6_add+0x310d/0x3fa0 net/ipv6/ip6_fib.c:1516 +Code: 00 48 8b 54 24 68 e8 42 22 00 00 48 85 c0 74 14 49 89 c6 e8 d5 d3 c2 f7 eb 5d e8 ce d3 c2 f7 e9 ca 00 00 00 e8 c4 d3 c2 f7 90 <0f> 0b 90 48 b8 00 00 00 00 00 fc ff df 48 8b 4c 24 38 80 3c 01 00 +RSP: 0018:ffffc90005067740 EFLAGS: 00010293 +RAX: ffffffff89cba5bc RBX: ffffc90005067ab0 RCX: ffff88801a2e9dc0 +RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000 +RBP: ffffc90005067980 R08: ffffffff89cbca85 R09: 1ffff110040d4b85 +R10: dffffc0000000000 R11: ffffed10040d4b86 R12: 00000000ffffffff +R13: 1ffff110051c3904 R14: ffff8880206a5c00 R15: ffff888028e1c820 +FS: 00007f763783c6c0(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007f763783bff8 CR3: 000000007f74d000 CR4: 00000000003506f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + +__ip6_ins_rt net/ipv6/route.c:1303 [inline] +ip6_route_add+0x88/0x120 net/ipv6/route.c:3847 +ipv6_route_ioctl+0x525/0x7b0 net/ipv6/route.c:4467 +inet6_ioctl+0x21a/0x270 net/ipv6/af_inet6.c:575 +sock_do_ioctl+0x152/0x460 net/socket.c:1220 +sock_ioctl+0x615/0x8c0 net/socket.c:1339 +vfs_ioctl fs/ioctl.c:51 [inline] +__do_sys_ioctl fs/ioctl.c:871 [inline] +__se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857 +do_syscall_x64 arch/x86/entry/common.c:51 [inline] +do_syscall_64+0x45/0x110 arch/x86/entry/common.c:82 + +Fixes: 7bbfe00e0252 ("ipv6: fix general protection fault in fib6_add()") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Cc: Wei Wang +Reviewed-by: David Ahern +Link: https://lore.kernel.org/r/20231129160630.3509216-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/ip6_fib.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index 5ff67cb8b6ace..92bc56028b8b6 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1351,13 +1351,9 @@ int fib6_add(struct fib6_node *root, struct fib6_info *rt, + if (!pn_leaf && !(pn->fn_flags & RTN_RTINFO)) { + pn_leaf = fib6_find_prefix(info->nl_net, table, + pn); +-#if RT6_DEBUG >= 2 +- if (!pn_leaf) { +- WARN_ON(!pn_leaf); ++ if (!pn_leaf) + pn_leaf = + info->nl_net->ipv6.fib6_null_entry; +- } +-#endif + fib6_info_hold(pn_leaf); + rcu_assign_pointer(pn->leaf, pn_leaf); + } +-- +2.42.0 + diff --git a/queue-4.19/net-arcnet-com20020-fix-error-handling.patch b/queue-4.19/net-arcnet-com20020-fix-error-handling.patch new file mode 100644 index 00000000000..0e470675f71 --- /dev/null +++ b/queue-4.19/net-arcnet-com20020-fix-error-handling.patch @@ -0,0 +1,137 @@ +From b096a86e010df52d1f14022353daf2caad62f4a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Mar 2021 14:08:36 -0400 +Subject: net: arcnet: com20020 fix error handling + +From: Tong Zhang + +[ Upstream commit 6577b9a551aedb86bca6d4438c28386361845108 ] + +There are two issues when handling error case in com20020pci_probe() + +1. priv might be not initialized yet when calling com20020pci_remove() +from com20020pci_probe(), since the priv is set at the very last but it +can jump to error handling in the middle and priv remains NULL. +2. memory leak - the net device is allocated in alloc_arcdev but not +properly released if error happens in the middle of the big for loop + +[ 1.529110] BUG: kernel NULL pointer dereference, address: 0000000000000008 +[ 1.531447] RIP: 0010:com20020pci_remove+0x15/0x60 [com20020_pci] +[ 1.536805] Call Trace: +[ 1.536939] com20020pci_probe+0x3f2/0x48c [com20020_pci] +[ 1.537226] local_pci_probe+0x48/0x80 +[ 1.539918] com20020pci_init+0x3f/0x1000 [com20020_pci] + +Signed-off-by: Tong Zhang +Signed-off-by: David S. Miller +Stable-dep-of: 6b17a597fc2f ("arcnet: restoring support for multiple Sohard Arcnet cards") +Signed-off-by: Sasha Levin +--- + drivers/net/arcnet/com20020-pci.c | 34 +++++++++++++++++-------------- + 1 file changed, 19 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c +index b4f8798d8c509..28dccbc0e8d8f 100644 +--- a/drivers/net/arcnet/com20020-pci.c ++++ b/drivers/net/arcnet/com20020-pci.c +@@ -127,6 +127,8 @@ static int com20020pci_probe(struct pci_dev *pdev, + int i, ioaddr, ret; + struct resource *r; + ++ ret = 0; ++ + if (pci_enable_device(pdev)) + return -EIO; + +@@ -142,6 +144,8 @@ static int com20020pci_probe(struct pci_dev *pdev, + priv->ci = ci; + mm = &ci->misc_map; + ++ pci_set_drvdata(pdev, priv); ++ + INIT_LIST_HEAD(&priv->list_dev); + + if (mm->size) { +@@ -164,7 +168,7 @@ static int com20020pci_probe(struct pci_dev *pdev, + dev = alloc_arcdev(device); + if (!dev) { + ret = -ENOMEM; +- goto out_port; ++ break; + } + dev->dev_port = i; + +@@ -181,7 +185,7 @@ static int com20020pci_probe(struct pci_dev *pdev, + pr_err("IO region %xh-%xh already allocated\n", + ioaddr, ioaddr + cm->size - 1); + ret = -EBUSY; +- goto out_port; ++ goto err_free_arcdev; + } + + /* Dummy access after Reset +@@ -219,18 +223,18 @@ static int com20020pci_probe(struct pci_dev *pdev, + if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) { + pr_err("IO address %Xh is empty!\n", ioaddr); + ret = -EIO; +- goto out_port; ++ goto err_free_arcdev; + } + if (com20020_check(dev)) { + ret = -EIO; +- goto out_port; ++ goto err_free_arcdev; + } + + card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev), + GFP_KERNEL); + if (!card) { + ret = -ENOMEM; +- goto out_port; ++ goto err_free_arcdev; + } + + card->index = i; +@@ -256,29 +260,29 @@ static int com20020pci_probe(struct pci_dev *pdev, + + ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); + if (ret) +- goto out_port; ++ goto err_free_arcdev; + + ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); + if (ret) +- goto out_port; ++ goto err_free_arcdev; + + dev_set_drvdata(&dev->dev, card); + + ret = com20020_found(dev, IRQF_SHARED); + if (ret) +- goto out_port; ++ goto err_free_arcdev; + + devm_arcnet_led_init(dev, dev->dev_id, i); + + list_add(&card->list, &priv->list_dev); +- } ++ continue; + +- pci_set_drvdata(pdev, priv); +- +- return 0; +- +-out_port: +- com20020pci_remove(pdev); ++err_free_arcdev: ++ free_arcdev(dev); ++ break; ++ } ++ if (ret) ++ com20020pci_remove(pdev); + return ret; + } + +-- +2.42.0 + diff --git a/queue-4.19/net-arcnet-fix-reset-flag-handling.patch b/queue-4.19/net-arcnet-fix-reset-flag-handling.patch new file mode 100644 index 00000000000..216c23fba9a --- /dev/null +++ b/queue-4.19/net-arcnet-fix-reset-flag-handling.patch @@ -0,0 +1,315 @@ +From 6fbe309fdf82021547ed2a5e173a5988f737fc6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Jan 2021 20:48:02 +0100 +Subject: net: arcnet: Fix RESET flag handling + +From: Ahmed S. Darwish + +[ Upstream commit 01365633bd1c836240f9bbf86bbeee749795480a ] + +The main arcnet interrupt handler calls arcnet_close() then +arcnet_open(), if the RESET status flag is encountered. + +This is invalid: + + 1) In general, interrupt handlers should never call ->ndo_stop() and + ->ndo_open() functions. They are usually full of blocking calls and + other methods that are expected to be called only from drivers + init and exit code paths. + + 2) arcnet_close() contains a del_timer_sync(). If the irq handler + interrupts the to-be-deleted timer, del_timer_sync() will just loop + forever. + + 3) arcnet_close() also calls tasklet_kill(), which has a warning if + called from irq context. + + 4) For device reset, the sequence "arcnet_close(); arcnet_open();" is + not complete. Some children arcnet drivers have special init/exit + code sequences, which then embed a call to arcnet_open() and + arcnet_close() accordingly. Check drivers/net/arcnet/com20020.c. + +Run the device RESET sequence from a scheduled workqueue instead. + +Signed-off-by: Ahmed S. Darwish +Signed-off-by: Sebastian Andrzej Siewior +Link: https://lore.kernel.org/r/20210128194802.727770-1-a.darwish@linutronix.de +Signed-off-by: Jakub Kicinski +Stable-dep-of: 6b17a597fc2f ("arcnet: restoring support for multiple Sohard Arcnet cards") +Signed-off-by: Sasha Levin +--- + drivers/net/arcnet/arc-rimi.c | 4 +- + drivers/net/arcnet/arcdevice.h | 6 +++ + drivers/net/arcnet/arcnet.c | 66 +++++++++++++++++++++++++++++-- + drivers/net/arcnet/com20020-isa.c | 4 +- + drivers/net/arcnet/com20020-pci.c | 2 +- + drivers/net/arcnet/com20020_cs.c | 2 +- + drivers/net/arcnet/com90io.c | 4 +- + drivers/net/arcnet/com90xx.c | 4 +- + 8 files changed, 78 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c +index a07e24970be42..3d0ce6d46a24e 100644 +--- a/drivers/net/arcnet/arc-rimi.c ++++ b/drivers/net/arcnet/arc-rimi.c +@@ -332,7 +332,7 @@ static int __init arc_rimi_init(void) + dev->irq = 9; + + if (arcrimi_probe(dev)) { +- free_netdev(dev); ++ free_arcdev(dev); + return -EIO; + } + +@@ -349,7 +349,7 @@ static void __exit arc_rimi_exit(void) + iounmap(lp->mem_start); + release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1); + free_irq(dev->irq, dev); +- free_netdev(dev); ++ free_arcdev(dev); + } + + #ifndef MODULE +diff --git a/drivers/net/arcnet/arcdevice.h b/drivers/net/arcnet/arcdevice.h +index d09b2b46ab63c..1ad5e4a03d23e 100644 +--- a/drivers/net/arcnet/arcdevice.h ++++ b/drivers/net/arcnet/arcdevice.h +@@ -303,6 +303,10 @@ struct arcnet_local { + + int excnak_pending; /* We just got an excesive nak interrupt */ + ++ /* RESET flag handling */ ++ int reset_in_progress; ++ struct work_struct reset_work; ++ + struct { + uint16_t sequence; /* sequence number (incs with each packet) */ + __be16 aborted_seq; +@@ -355,7 +359,9 @@ void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc) + + void arcnet_unregister_proto(struct ArcProto *proto); + irqreturn_t arcnet_interrupt(int irq, void *dev_id); ++ + struct net_device *alloc_arcdev(const char *name); ++void free_arcdev(struct net_device *dev); + + int arcnet_open(struct net_device *dev); + int arcnet_close(struct net_device *dev); +diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c +index 2b112d3d85409..cf652c76af85e 100644 +--- a/drivers/net/arcnet/arcnet.c ++++ b/drivers/net/arcnet/arcnet.c +@@ -387,10 +387,44 @@ static void arcnet_timer(struct timer_list *t) + struct arcnet_local *lp = from_timer(lp, t, timer); + struct net_device *dev = lp->dev; + +- if (!netif_carrier_ok(dev)) { ++ spin_lock_irq(&lp->lock); ++ ++ if (!lp->reset_in_progress && !netif_carrier_ok(dev)) { + netif_carrier_on(dev); + netdev_info(dev, "link up\n"); + } ++ ++ spin_unlock_irq(&lp->lock); ++} ++ ++static void reset_device_work(struct work_struct *work) ++{ ++ struct arcnet_local *lp; ++ struct net_device *dev; ++ ++ lp = container_of(work, struct arcnet_local, reset_work); ++ dev = lp->dev; ++ ++ /* Do not bring the network interface back up if an ifdown ++ * was already done. ++ */ ++ if (!netif_running(dev) || !lp->reset_in_progress) ++ return; ++ ++ rtnl_lock(); ++ ++ /* Do another check, in case of an ifdown that was triggered in ++ * the small race window between the exit condition above and ++ * acquiring RTNL. ++ */ ++ if (!netif_running(dev) || !lp->reset_in_progress) ++ goto out; ++ ++ dev_close(dev); ++ dev_open(dev, NULL); ++ ++out: ++ rtnl_unlock(); + } + + static void arcnet_reply_tasklet(unsigned long data) +@@ -452,12 +486,25 @@ struct net_device *alloc_arcdev(const char *name) + lp->dev = dev; + spin_lock_init(&lp->lock); + timer_setup(&lp->timer, arcnet_timer, 0); ++ INIT_WORK(&lp->reset_work, reset_device_work); + } + + return dev; + } + EXPORT_SYMBOL(alloc_arcdev); + ++void free_arcdev(struct net_device *dev) ++{ ++ struct arcnet_local *lp = netdev_priv(dev); ++ ++ /* Do not cancel this at ->ndo_close(), as the workqueue itself ++ * indirectly calls the ifdown path through dev_close(). ++ */ ++ cancel_work_sync(&lp->reset_work); ++ free_netdev(dev); ++} ++EXPORT_SYMBOL(free_arcdev); ++ + /* Open/initialize the board. This is called sometime after booting when + * the 'ifconfig' program is run. + * +@@ -587,6 +634,10 @@ int arcnet_close(struct net_device *dev) + + /* shut down the card */ + lp->hw.close(dev); ++ ++ /* reset counters */ ++ lp->reset_in_progress = 0; ++ + module_put(lp->hw.owner); + return 0; + } +@@ -820,6 +871,9 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id) + + spin_lock_irqsave(&lp->lock, flags); + ++ if (lp->reset_in_progress) ++ goto out; ++ + /* RESET flag was enabled - if device is not running, we must + * clear it right away (but nothing else). + */ +@@ -852,11 +906,14 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id) + if (status & RESETflag) { + arc_printk(D_NORMAL, dev, "spurious reset (status=%Xh)\n", + status); +- arcnet_close(dev); +- arcnet_open(dev); ++ ++ lp->reset_in_progress = 1; ++ netif_stop_queue(dev); ++ netif_carrier_off(dev); ++ schedule_work(&lp->reset_work); + + /* get out of the interrupt handler! */ +- break; ++ goto out; + } + /* RX is inhibited - we must have received something. + * Prepare to receive into the next buffer. +@@ -1052,6 +1109,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id) + udelay(1); + lp->hw.intmask(dev, lp->intmask); + ++out: + spin_unlock_irqrestore(&lp->lock, flags); + return retval; + } +diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c +index 38fa60ddaf2ea..fada3f23970ee 100644 +--- a/drivers/net/arcnet/com20020-isa.c ++++ b/drivers/net/arcnet/com20020-isa.c +@@ -169,7 +169,7 @@ static int __init com20020_init(void) + dev->irq = 9; + + if (com20020isa_probe(dev)) { +- free_netdev(dev); ++ free_arcdev(dev); + return -EIO; + } + +@@ -182,7 +182,7 @@ static void __exit com20020_exit(void) + unregister_netdev(my_dev); + free_irq(my_dev->irq, my_dev); + release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE); +- free_netdev(my_dev); ++ free_arcdev(my_dev); + } + + #ifndef MODULE +diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c +index 9f44e2e458df1..b4f8798d8c509 100644 +--- a/drivers/net/arcnet/com20020-pci.c ++++ b/drivers/net/arcnet/com20020-pci.c +@@ -294,7 +294,7 @@ static void com20020pci_remove(struct pci_dev *pdev) + + unregister_netdev(dev); + free_irq(dev->irq, dev); +- free_netdev(dev); ++ free_arcdev(dev); + } + } + +diff --git a/drivers/net/arcnet/com20020_cs.c b/drivers/net/arcnet/com20020_cs.c +index cf607ffcf358e..9cc5eb6a8e905 100644 +--- a/drivers/net/arcnet/com20020_cs.c ++++ b/drivers/net/arcnet/com20020_cs.c +@@ -177,7 +177,7 @@ static void com20020_detach(struct pcmcia_device *link) + dev = info->dev; + if (dev) { + dev_dbg(&link->dev, "kfree...\n"); +- free_netdev(dev); ++ free_arcdev(dev); + } + dev_dbg(&link->dev, "kfree2...\n"); + kfree(info); +diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c +index 4e56aaf2b9843..e9fc0577ddc0b 100644 +--- a/drivers/net/arcnet/com90io.c ++++ b/drivers/net/arcnet/com90io.c +@@ -394,7 +394,7 @@ static int __init com90io_init(void) + err = com90io_probe(dev); + + if (err) { +- free_netdev(dev); ++ free_arcdev(dev); + return err; + } + +@@ -417,7 +417,7 @@ static void __exit com90io_exit(void) + + free_irq(dev->irq, dev); + release_region(dev->base_addr, ARCNET_TOTAL_SIZE); +- free_netdev(dev); ++ free_arcdev(dev); + } + + module_init(com90io_init) +diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c +index ca4a57c30bf89..5e38a2d6623cc 100644 +--- a/drivers/net/arcnet/com90xx.c ++++ b/drivers/net/arcnet/com90xx.c +@@ -554,7 +554,7 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem, + err_release_mem: + release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1); + err_free_dev: +- free_netdev(dev); ++ free_arcdev(dev); + return -EIO; + } + +@@ -672,7 +672,7 @@ static void __exit com90xx_exit(void) + release_region(dev->base_addr, ARCNET_TOTAL_SIZE); + release_mem_region(dev->mem_start, + dev->mem_end - dev->mem_start + 1); +- free_netdev(dev); ++ free_arcdev(dev); + } + } + +-- +2.42.0 + diff --git a/queue-4.19/net-core-dev-add-extack-argument-to-dev_open.patch b/queue-4.19/net-core-dev-add-extack-argument-to-dev_open.patch new file mode 100644 index 00000000000..901a127857e --- /dev/null +++ b/queue-4.19/net-core-dev-add-extack-argument-to-dev_open.patch @@ -0,0 +1,407 @@ +From 74d905dd1c4b5ea5b425d11109b3cbb3c587200a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Dec 2018 17:05:36 +0000 +Subject: net: core: dev: Add extack argument to dev_open() + +From: Petr Machata + +[ Upstream commit 00f54e68924eaf075f3f24be18557899d347bc4a ] + +In order to pass extack together with NETDEV_PRE_UP notifications, it's +necessary to route the extack to __dev_open() from diverse (possibly +indirect) callers. One prominent API through which the notification is +invoked is dev_open(). + +Therefore extend dev_open() with and extra extack argument and update +all users. Most of the calls end up just encoding NULL, but bond and +team drivers have the extack readily available. + +Signed-off-by: Petr Machata +Acked-by: Jiri Pirko +Reviewed-by: Ido Schimmel +Reviewed-by: David Ahern +Signed-off-by: David S. Miller +Stable-dep-of: 6b17a597fc2f ("arcnet: restoring support for multiple Sohard Arcnet cards") +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 2 +- + drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c | 2 +- + drivers/net/ethernet/cisco/enic/enic_ethtool.c | 2 +- + drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 2 +- + drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 2 +- + drivers/net/ethernet/sfc/ethtool.c | 2 +- + drivers/net/ethernet/sfc/falcon/ethtool.c | 2 +- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- + drivers/net/hyperv/netvsc_drv.c | 4 ++-- + drivers/net/net_failover.c | 8 ++++---- + drivers/net/team/team.c | 2 +- + drivers/net/wireless/intersil/hostap/hostap_main.c | 2 +- + drivers/s390/net/qeth_l2_main.c | 2 +- + drivers/s390/net/qeth_l3_main.c | 2 +- + drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 2 +- + drivers/staging/unisys/visornic/visornic_main.c | 2 +- + include/linux/netdevice.h | 2 +- + net/bluetooth/6lowpan.c | 2 +- + net/core/dev.c | 5 +++-- + net/core/netpoll.c | 2 +- + net/ipv4/ipmr.c | 4 ++-- + net/ipv6/addrconf.c | 2 +- + net/ipv6/ip6mr.c | 2 +- + 23 files changed, 30 insertions(+), 29 deletions(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 79b36f1c50aec..198e33893f9b2 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1563,7 +1563,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, + slave_dev->flags |= IFF_SLAVE; + + /* open the slave since the application closed it */ +- res = dev_open(slave_dev); ++ res = dev_open(slave_dev, extack); + if (res) { + netdev_dbg(bond_dev, "Opening slave %s failed\n", slave_dev->name); + goto err_restore_mac; +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c +index 08c9fa6ca71f2..f7ee481560c6d 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c +@@ -390,7 +390,7 @@ static int aq_set_ringparam(struct net_device *ndev, + } + } + if (ndev_running) +- err = dev_open(ndev); ++ err = dev_open(ndev, NULL); + + err_exit: + return err; +diff --git a/drivers/net/ethernet/cisco/enic/enic_ethtool.c b/drivers/net/ethernet/cisco/enic/enic_ethtool.c +index f42f7a6e15591..ebd5c2cf1efec 100644 +--- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c ++++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c +@@ -241,7 +241,7 @@ static int enic_set_ringparam(struct net_device *netdev, + } + enic_init_vnic_resources(enic); + if (running) { +- err = dev_open(netdev); ++ err = dev_open(netdev, NULL); + if (err) + goto err_out; + } +diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +index f453cebf758c6..3784db7b3a0df 100644 +--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c ++++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +@@ -632,7 +632,7 @@ static void hns_nic_self_test(struct net_device *ndev, + clear_bit(NIC_STATE_TESTING, &priv->state); + + if (if_running) +- (void)dev_open(ndev); ++ (void)dev_open(ndev, NULL); + } + /* Online tests aren't run; pass by default */ + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +index 1cb6f95f3a946..cc807d4773815 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +@@ -770,7 +770,7 @@ static int hns3_set_ringparam(struct net_device *ndev, + } + + if (if_running) +- ret = dev_open(ndev); ++ ret = dev_open(ndev, NULL); + + return ret; + } +diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c +index 82b32c742d69e..033aa6e1cefa2 100644 +--- a/drivers/net/ethernet/sfc/ethtool.c ++++ b/drivers/net/ethernet/sfc/ethtool.c +@@ -533,7 +533,7 @@ static void efx_ethtool_self_test(struct net_device *net_dev, + /* We need rx buffers and interrupts. */ + already_up = (efx->net_dev->flags & IFF_UP); + if (!already_up) { +- rc = dev_open(efx->net_dev); ++ rc = dev_open(efx->net_dev, NULL); + if (rc) { + netif_err(efx, drv, efx->net_dev, + "failed opening device.\n"); +diff --git a/drivers/net/ethernet/sfc/falcon/ethtool.c b/drivers/net/ethernet/sfc/falcon/ethtool.c +index 1ccdb7a82e2a7..72cedec945c18 100644 +--- a/drivers/net/ethernet/sfc/falcon/ethtool.c ++++ b/drivers/net/ethernet/sfc/falcon/ethtool.c +@@ -517,7 +517,7 @@ static void ef4_ethtool_self_test(struct net_device *net_dev, + /* We need rx buffers and interrupts. */ + already_up = (efx->net_dev->flags & IFF_UP); + if (!already_up) { +- rc = dev_open(efx->net_dev); ++ rc = dev_open(efx->net_dev, NULL); + if (rc) { + netif_err(efx, drv, efx->net_dev, + "failed opening device.\n"); +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 3e35cdf0d2b76..c4ef495833a6c 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -4149,7 +4149,7 @@ static void stmmac_reset_subtask(struct stmmac_priv *priv) + + set_bit(STMMAC_DOWN, &priv->state); + dev_close(priv->dev); +- dev_open(priv->dev); ++ dev_open(priv->dev, NULL); + clear_bit(STMMAC_DOWN, &priv->state); + clear_bit(STMMAC_RESETING, &priv->state); + rtnl_unlock(); +diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c +index ce17917b6f76f..af5d82e6ba22c 100644 +--- a/drivers/net/hyperv/netvsc_drv.c ++++ b/drivers/net/hyperv/netvsc_drv.c +@@ -146,7 +146,7 @@ static int netvsc_open(struct net_device *net) + * slave as up. If open fails, then slave will be + * still be offline (and not used). + */ +- ret = dev_open(vf_netdev); ++ ret = dev_open(vf_netdev, NULL); + if (ret) + netdev_warn(net, + "unable to open slave: %s: %d\n", +@@ -2082,7 +2082,7 @@ static void __netvsc_vf_setup(struct net_device *ndev, + netif_addr_unlock_bh(ndev); + + if (netif_running(ndev)) { +- ret = dev_open(vf_netdev); ++ ret = dev_open(vf_netdev, NULL); + if (ret) + netdev_warn(vf_netdev, + "unable to open: %d\n", ret); +diff --git a/drivers/net/net_failover.c b/drivers/net/net_failover.c +index 57273188b71e5..5973ee49dc785 100644 +--- a/drivers/net/net_failover.c ++++ b/drivers/net/net_failover.c +@@ -41,14 +41,14 @@ static int net_failover_open(struct net_device *dev) + + primary_dev = rtnl_dereference(nfo_info->primary_dev); + if (primary_dev) { +- err = dev_open(primary_dev); ++ err = dev_open(primary_dev, NULL); + if (err) + goto err_primary_open; + } + + standby_dev = rtnl_dereference(nfo_info->standby_dev); + if (standby_dev) { +- err = dev_open(standby_dev); ++ err = dev_open(standby_dev, NULL); + if (err) + goto err_standby_open; + } +@@ -519,7 +519,7 @@ static int net_failover_slave_register(struct net_device *slave_dev, + dev_hold(slave_dev); + + if (netif_running(failover_dev)) { +- err = dev_open(slave_dev); ++ err = dev_open(slave_dev, NULL); + if (err && (err != -EBUSY)) { + netdev_err(failover_dev, "Opening slave %s failed err:%d\n", + slave_dev->name, err); +@@ -682,7 +682,7 @@ static int net_failover_slave_name_change(struct net_device *slave_dev, + /* We need to bring up the slave after the rename by udev in case + * open failed with EBUSY when it was registered. + */ +- dev_open(slave_dev); ++ dev_open(slave_dev, NULL); + + return 0; + } +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index 08f9530fd5b15..9e17b2022ee4e 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -1217,7 +1217,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev, + goto err_port_enter; + } + +- err = dev_open(port_dev); ++ err = dev_open(port_dev, extack); + if (err) { + netdev_dbg(dev, "Device %s opening failed\n", + portname); +diff --git a/drivers/net/wireless/intersil/hostap/hostap_main.c b/drivers/net/wireless/intersil/hostap/hostap_main.c +index 012930d354344..b0e7c0a0617e4 100644 +--- a/drivers/net/wireless/intersil/hostap/hostap_main.c ++++ b/drivers/net/wireless/intersil/hostap/hostap_main.c +@@ -690,7 +690,7 @@ static int prism2_open(struct net_device *dev) + /* Master radio interface is needed for all operation, so open + * it automatically when any virtual net_device is opened. */ + local->master_dev_auto_open = 1; +- dev_open(local->dev); ++ dev_open(local->dev, NULL); + } + + netif_device_attach(dev); +diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c +index 8d30f9ac3e9d5..1663e4b23dd79 100644 +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -1050,7 +1050,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) + qeth_l2_set_rx_mode(card->dev); + } else { + rtnl_lock(); +- dev_open(card->dev); ++ dev_open(card->dev, NULL); + rtnl_unlock(); + } + } +diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c +index 52e0ae4dc7241..f21ff257c8999 100644 +--- a/drivers/s390/net/qeth_l3_main.c ++++ b/drivers/s390/net/qeth_l3_main.c +@@ -2699,7 +2699,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) + __qeth_l3_open(card->dev); + qeth_l3_set_rx_mode(card->dev); + } else { +- dev_open(card->dev); ++ dev_open(card->dev, NULL); + } + rtnl_unlock(); + } +diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c +index 8549e809363e4..917d5b165f8c2 100644 +--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c ++++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c +@@ -1126,7 +1126,7 @@ static int ethsw_open(struct ethsw_core *ethsw) + + for (i = 0; i < ethsw->sw_attr.num_ifs; i++) { + port_priv = ethsw->ports[i]; +- err = dev_open(port_priv->netdev); ++ err = dev_open(port_priv->netdev, NULL); + if (err) { + netdev_err(port_priv->netdev, "dev_open err %d\n", err); + return err; +diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c +index 3647b8f1ed286..5eeb4b93b45bc 100644 +--- a/drivers/staging/unisys/visornic/visornic_main.c ++++ b/drivers/staging/unisys/visornic/visornic_main.c +@@ -2095,7 +2095,7 @@ static int visornic_resume(struct visor_device *dev, + mod_timer(&devdata->irq_poll_timer, msecs_to_jiffies(2)); + + rtnl_lock(); +- dev_open(netdev); ++ dev_open(netdev, NULL); + rtnl_unlock(); + + complete_func(dev, 0); +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index ac87fcc4d44b4..fa37b2eab50a2 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -2602,7 +2602,7 @@ struct net_device *dev_get_by_name(struct net *net, const char *name); + struct net_device *dev_get_by_name_rcu(struct net *net, const char *name); + struct net_device *__dev_get_by_name(struct net *net, const char *name); + int dev_alloc_name(struct net_device *dev, const char *name); +-int dev_open(struct net_device *dev); ++int dev_open(struct net_device *dev, struct netlink_ext_ack *extack); + void dev_close(struct net_device *dev); + void dev_close_many(struct list_head *head, bool unlink); + void dev_disable_lro(struct net_device *dev); +diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c +index 4530ffb2481a4..c6d1b27fa391c 100644 +--- a/net/bluetooth/6lowpan.c ++++ b/net/bluetooth/6lowpan.c +@@ -614,7 +614,7 @@ static void ifup(struct net_device *netdev) + int err; + + rtnl_lock(); +- err = dev_open(netdev); ++ err = dev_open(netdev, NULL); + if (err < 0) + BT_INFO("iface %s cannot be opened (%d)", netdev->name, err); + rtnl_unlock(); +diff --git a/net/core/dev.c b/net/core/dev.c +index 0f9214fb36e01..63d5ec728c8e6 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1417,7 +1417,8 @@ static int __dev_open(struct net_device *dev) + + /** + * dev_open - prepare an interface for use. +- * @dev: device to open ++ * @dev: device to open ++ * @extack: netlink extended ack + * + * Takes a device from down to up state. The device's private open + * function is invoked and then the multicast lists are loaded. Finally +@@ -1427,7 +1428,7 @@ static int __dev_open(struct net_device *dev) + * Calling this function on an active interface is a nop. On a failure + * a negative errno code is returned. + */ +-int dev_open(struct net_device *dev) ++int dev_open(struct net_device *dev, struct netlink_ext_ack *extack) + { + int ret; + +diff --git a/net/core/netpoll.c b/net/core/netpoll.c +index 08f0da9e6a809..3808955c87355 100644 +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -696,7 +696,7 @@ int netpoll_setup(struct netpoll *np) + + np_info(np, "device %s not up yet, forcing it\n", np->dev_name); + +- err = dev_open(ndev); ++ err = dev_open(ndev, NULL); + + if (err) { + np_err(np, "failed to open %s\n", ndev->name); +diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c +index 2085af224a416..9aeb4d97f514c 100644 +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -510,7 +510,7 @@ static struct net_device *ipmr_new_tunnel(struct net *net, struct vifctl *v) + dev->flags |= IFF_MULTICAST; + if (!ipmr_init_vif_indev(dev)) + goto failure; +- if (dev_open(dev)) ++ if (dev_open(dev, NULL)) + goto failure; + dev_hold(dev); + } +@@ -593,7 +593,7 @@ static struct net_device *ipmr_reg_vif(struct net *net, struct mr_table *mrt) + + if (!ipmr_init_vif_indev(dev)) + goto failure; +- if (dev_open(dev)) ++ if (dev_open(dev, NULL)) + goto failure; + + dev_hold(dev); +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 5ffa8777ab098..6e2de18d65df4 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -2823,7 +2823,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg) + dev = __dev_get_by_name(net, p.name); + if (!dev) + goto err_exit; +- err = dev_open(dev); ++ err = dev_open(dev, NULL); + } + } + #endif +diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c +index 329bad6cbb768..36d8b763b26f9 100644 +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -658,7 +658,7 @@ static struct net_device *ip6mr_reg_vif(struct net *net, struct mr_table *mrt) + return NULL; + } + +- if (dev_open(dev)) ++ if (dev_open(dev, NULL)) + goto failure; + + dev_hold(dev); +-- +2.42.0 + diff --git a/queue-4.19/net-hns-fix-fake-link-up-on-xge-port.patch b/queue-4.19/net-hns-fix-fake-link-up-on-xge-port.patch new file mode 100644 index 00000000000..7aa83a348b7 --- /dev/null +++ b/queue-4.19/net-hns-fix-fake-link-up-on-xge-port.patch @@ -0,0 +1,74 @@ +From e44d8f4516204312317826c37e75fb9bc65a827c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Dec 2023 22:32:32 +0800 +Subject: net: hns: fix fake link up on xge port + +From: Yonglong Liu + +[ Upstream commit f708aba40f9c1eeb9c7e93ed4863b5f85b09b288 ] + +If a xge port just connect with an optical module and no fiber, +it may have a fake link up because there may be interference on +the hardware. This patch adds an anti-shake to avoid the problem. +And the time of anti-shake is base on tests. + +Fixes: b917078c1c10 ("net: hns: Add ACPI support to check SFP present") +Signed-off-by: Yonglong Liu +Signed-off-by: Jijie Shao +Reviewed-by: Wojciech Drewek +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 29 +++++++++++++++++++ + 1 file changed, 29 insertions(+) + +diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c +index cfdc92de9dc0e..d2791bcff5d49 100644 +--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c ++++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c +@@ -70,6 +70,27 @@ static enum mac_mode hns_get_enet_interface(const struct hns_mac_cb *mac_cb) + } + } + ++static u32 hns_mac_link_anti_shake(struct mac_driver *mac_ctrl_drv) ++{ ++#define HNS_MAC_LINK_WAIT_TIME 5 ++#define HNS_MAC_LINK_WAIT_CNT 40 ++ ++ u32 link_status = 0; ++ int i; ++ ++ if (!mac_ctrl_drv->get_link_status) ++ return link_status; ++ ++ for (i = 0; i < HNS_MAC_LINK_WAIT_CNT; i++) { ++ msleep(HNS_MAC_LINK_WAIT_TIME); ++ mac_ctrl_drv->get_link_status(mac_ctrl_drv, &link_status); ++ if (!link_status) ++ break; ++ } ++ ++ return link_status; ++} ++ + void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status) + { + struct mac_driver *mac_ctrl_drv; +@@ -87,6 +108,14 @@ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status) + &sfp_prsnt); + if (!ret) + *link_status = *link_status && sfp_prsnt; ++ ++ /* for FIBER port, it may have a fake link up. ++ * when the link status changes from down to up, we need to do ++ * anti-shake. the anti-shake time is base on tests. ++ * only FIBER port need to do this. ++ */ ++ if (*link_status && !mac_cb->link) ++ *link_status = hns_mac_link_anti_shake(mac_ctrl_drv); + } + + mac_cb->link = *link_status; +-- +2.42.0 + diff --git a/queue-4.19/netfilter-xt_owner-add-supplementary-groups-option.patch b/queue-4.19/netfilter-xt_owner-add-supplementary-groups-option.patch new file mode 100644 index 00000000000..247cf531198 --- /dev/null +++ b/queue-4.19/netfilter-xt_owner-add-supplementary-groups-option.patch @@ -0,0 +1,81 @@ +From d5956836167115795099a028241c1afcc5b95ccf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 May 2019 13:46:22 +0200 +Subject: netfilter: xt_owner: Add supplementary groups option + +From: Lukasz Pawelczyk + +[ Upstream commit ea6cc2fd8a2b89ab6dcd096ba6dbc1ecbdf26564 ] + +The XT_OWNER_SUPPL_GROUPS flag causes GIDs specified with XT_OWNER_GID +to be also checked in the supplementary groups of a process. + +f_cred->group_info cannot be modified during its lifetime and f_cred +holds a reference to it so it's safe to use. + +Signed-off-by: Lukasz Pawelczyk +Signed-off-by: Pablo Neira Ayuso +Stable-dep-of: 7ae836a3d630 ("netfilter: xt_owner: Fix for unsafe access of sk->sk_socket") +Signed-off-by: Sasha Levin +--- + include/uapi/linux/netfilter/xt_owner.h | 7 ++++--- + net/netfilter/xt_owner.c | 23 ++++++++++++++++++++--- + 2 files changed, 24 insertions(+), 6 deletions(-) + +diff --git a/include/uapi/linux/netfilter/xt_owner.h b/include/uapi/linux/netfilter/xt_owner.h +index fa3ad84957d50..9e98c09eda327 100644 +--- a/include/uapi/linux/netfilter/xt_owner.h ++++ b/include/uapi/linux/netfilter/xt_owner.h +@@ -5,9 +5,10 @@ + #include + + enum { +- XT_OWNER_UID = 1 << 0, +- XT_OWNER_GID = 1 << 1, +- XT_OWNER_SOCKET = 1 << 2, ++ XT_OWNER_UID = 1 << 0, ++ XT_OWNER_GID = 1 << 1, ++ XT_OWNER_SOCKET = 1 << 2, ++ XT_OWNER_SUPPL_GROUPS = 1 << 3, + }; + + struct xt_owner_match_info { +diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c +index 46686fb73784b..a8784502aca69 100644 +--- a/net/netfilter/xt_owner.c ++++ b/net/netfilter/xt_owner.c +@@ -91,11 +91,28 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par) + } + + if (info->match & XT_OWNER_GID) { ++ unsigned int i, match = false; + kgid_t gid_min = make_kgid(net->user_ns, info->gid_min); + kgid_t gid_max = make_kgid(net->user_ns, info->gid_max); +- if ((gid_gte(filp->f_cred->fsgid, gid_min) && +- gid_lte(filp->f_cred->fsgid, gid_max)) ^ +- !(info->invert & XT_OWNER_GID)) ++ struct group_info *gi = filp->f_cred->group_info; ++ ++ if (gid_gte(filp->f_cred->fsgid, gid_min) && ++ gid_lte(filp->f_cred->fsgid, gid_max)) ++ match = true; ++ ++ if (!match && (info->match & XT_OWNER_SUPPL_GROUPS) && gi) { ++ for (i = 0; i < gi->ngroups; ++i) { ++ kgid_t group = gi->gid[i]; ++ ++ if (gid_gte(group, gid_min) && ++ gid_lte(group, gid_max)) { ++ match = true; ++ break; ++ } ++ } ++ } ++ ++ if (match ^ !(info->invert & XT_OWNER_GID)) + return false; + } + +-- +2.42.0 + diff --git a/queue-4.19/netfilter-xt_owner-fix-for-unsafe-access-of-sk-sk_so.patch b/queue-4.19/netfilter-xt_owner-fix-for-unsafe-access-of-sk-sk_so.patch new file mode 100644 index 00000000000..df7c295430b --- /dev/null +++ b/queue-4.19/netfilter-xt_owner-fix-for-unsafe-access-of-sk-sk_so.patch @@ -0,0 +1,71 @@ +From a4f6458a9bae3dc5635ec3b90f42483f27c47b74 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Dec 2023 21:58:12 +0100 +Subject: netfilter: xt_owner: Fix for unsafe access of sk->sk_socket + +From: Phil Sutter + +[ Upstream commit 7ae836a3d630e146b732fe8ef7d86b243748751f ] + +A concurrently running sock_orphan() may NULL the sk_socket pointer in +between check and deref. Follow other users (like nft_meta.c for +instance) and acquire sk_callback_lock before dereferencing sk_socket. + +Fixes: 0265ab44bacc ("[NETFILTER]: merge ipt_owner/ip6t_owner in xt_owner") +Reported-by: Jann Horn +Signed-off-by: Phil Sutter +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/xt_owner.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c +index a8784502aca69..0c101b25cacf6 100644 +--- a/net/netfilter/xt_owner.c ++++ b/net/netfilter/xt_owner.c +@@ -76,18 +76,23 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par) + */ + return false; + +- filp = sk->sk_socket->file; +- if (filp == NULL) ++ read_lock_bh(&sk->sk_callback_lock); ++ filp = sk->sk_socket ? sk->sk_socket->file : NULL; ++ if (filp == NULL) { ++ read_unlock_bh(&sk->sk_callback_lock); + return ((info->match ^ info->invert) & + (XT_OWNER_UID | XT_OWNER_GID)) == 0; ++ } + + if (info->match & XT_OWNER_UID) { + kuid_t uid_min = make_kuid(net->user_ns, info->uid_min); + kuid_t uid_max = make_kuid(net->user_ns, info->uid_max); + if ((uid_gte(filp->f_cred->fsuid, uid_min) && + uid_lte(filp->f_cred->fsuid, uid_max)) ^ +- !(info->invert & XT_OWNER_UID)) ++ !(info->invert & XT_OWNER_UID)) { ++ read_unlock_bh(&sk->sk_callback_lock); + return false; ++ } + } + + if (info->match & XT_OWNER_GID) { +@@ -112,10 +117,13 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par) + } + } + +- if (match ^ !(info->invert & XT_OWNER_GID)) ++ if (match ^ !(info->invert & XT_OWNER_GID)) { ++ read_unlock_bh(&sk->sk_callback_lock); + return false; ++ } + } + ++ read_unlock_bh(&sk->sk_callback_lock); + return true; + } + +-- +2.42.0 + diff --git a/queue-4.19/series b/queue-4.19/series index b9b74ddcfa5..49336a55c7c 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -10,3 +10,14 @@ tg3-move-the-rt-x_dropped-counters-to-tg3_napi.patch tg3-increment-tx_dropped-in-tg3_tso_bug.patch kconfig-fix-memory-leak-from-range-properties.patch drm-amdgpu-correct-chunk_ptr-to-a-pointer-to-chunk.patch +ipv6-fix-potential-null-deref-in-fib6_add.patch +hv_netvsc-rndis_filter-needs-to-select-nls.patch +net-core-dev-add-extack-argument-to-dev_open.patch +net-arcnet-fix-reset-flag-handling.patch +net-arcnet-com20020-fix-error-handling.patch +arcnet-restoring-support-for-multiple-sohard-arcnet-.patch +ipv4-ip_gre-avoid-skb_pull-failure-in-ipgre_xmit.patch +net-hns-fix-fake-link-up-on-xge-port.patch +netfilter-xt_owner-add-supplementary-groups-option.patch +netfilter-xt_owner-fix-for-unsafe-access-of-sk-sk_so.patch +tcp-do-not-accept-ack-of-bytes-we-never-sent.patch diff --git a/queue-4.19/tcp-do-not-accept-ack-of-bytes-we-never-sent.patch b/queue-4.19/tcp-do-not-accept-ack-of-bytes-we-never-sent.patch new file mode 100644 index 00000000000..62fc58cff77 --- /dev/null +++ b/queue-4.19/tcp-do-not-accept-ack-of-bytes-we-never-sent.patch @@ -0,0 +1,106 @@ +From 74b8c9ae578797e7fbb3a0ef72052fe7c3af546b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Dec 2023 16:18:41 +0000 +Subject: tcp: do not accept ACK of bytes we never sent + +From: Eric Dumazet + +[ Upstream commit 3d501dd326fb1c73f1b8206d4c6e1d7b15c07e27 ] + +This patch is based on a detailed report and ideas from Yepeng Pan +and Christian Rossow. + +ACK seq validation is currently following RFC 5961 5.2 guidelines: + + The ACK value is considered acceptable only if + it is in the range of ((SND.UNA - MAX.SND.WND) <= SEG.ACK <= + SND.NXT). All incoming segments whose ACK value doesn't satisfy the + above condition MUST be discarded and an ACK sent back. It needs to + be noted that RFC 793 on page 72 (fifth check) says: "If the ACK is a + duplicate (SEG.ACK < SND.UNA), it can be ignored. If the ACK + acknowledges something not yet sent (SEG.ACK > SND.NXT) then send an + ACK, drop the segment, and return". The "ignored" above implies that + the processing of the incoming data segment continues, which means + the ACK value is treated as acceptable. This mitigation makes the + ACK check more stringent since any ACK < SND.UNA wouldn't be + accepted, instead only ACKs that are in the range ((SND.UNA - + MAX.SND.WND) <= SEG.ACK <= SND.NXT) get through. + +This can be refined for new (and possibly spoofed) flows, +by not accepting ACK for bytes that were never sent. + +This greatly improves TCP security at a little cost. + +I added a Fixes: tag to make sure this patch will reach stable trees, +even if the 'blamed' patch was adhering to the RFC. + +tp->bytes_acked was added in linux-4.2 + +Following packetdrill test (courtesy of Yepeng Pan) shows +the issue at hand: + +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 ++0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 ++0 bind(3, ..., ...) = 0 ++0 listen(3, 1024) = 0 + +// ---------------- Handshake ------------------- // + +// when window scale is set to 14 the window size can be extended to +// 65535 * (2^14) = 1073725440. Linux would accept an ACK packet +// with ack number in (Server_ISN+1-1073725440. Server_ISN+1) +// ,though this ack number acknowledges some data never +// sent by the server. + ++0 < S 0:0(0) win 65535 ++0 > S. 0:0(0) ack 1 <...> ++0 < . 1:1(0) ack 1 win 65535 ++0 accept(3, ..., ...) = 4 + +// For the established connection, we send an ACK packet, +// the ack packet uses ack number 1 - 1073725300 + 2^32, +// where 2^32 is used to wrap around. +// Note: we used 1073725300 instead of 1073725440 to avoid possible +// edge cases. +// 1 - 1073725300 + 2^32 = 3221241997 + +// Oops, old kernels happily accept this packet. ++0 < . 1:1001(1000) ack 3221241997 win 65535 + +// After the kernel fix the following will be replaced by a challenge ACK, +// and prior malicious frame would be dropped. ++0 > . 1:1(0) ack 1001 + +Fixes: 354e4aa391ed ("tcp: RFC 5961 5.2 Blind Data Injection Attack Mitigation") +Signed-off-by: Eric Dumazet +Reported-by: Yepeng Pan +Reported-by: Christian Rossow +Acked-by: Neal Cardwell +Link: https://lore.kernel.org/r/20231205161841.2702925-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp_input.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 0052a6194cc1a..407ad07dc5985 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -3640,8 +3640,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) + * then we can probably ignore it. + */ + if (before(ack, prior_snd_una)) { ++ u32 max_window; ++ ++ /* do not accept ACK for bytes we never sent. */ ++ max_window = min_t(u64, tp->max_window, tp->bytes_acked); + /* RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] */ +- if (before(ack, prior_snd_una - tp->max_window)) { ++ if (before(ack, prior_snd_una - max_window)) { + if (!(flag & FLAG_NO_CHALLENGE_ACK)) + tcp_send_challenge_ack(sk, skb); + return -1; +-- +2.42.0 + -- 2.47.3