From bd3b0bb742e48d1f50e1be6b7cfa7d267184111f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 2 Mar 2020 17:04:28 +0100 Subject: [PATCH] 4.19-stable patches added patches: ipv6-fix-nlmsg_flags-when-splitting-a-multipath-route.patch ipv6-fix-route-replacement-with-dev-only-route.patch net-fib_rules-correctly-set-table-field-when-table-number-exceeds-8-bits.patch net-mscc-fix-in-frame-extraction.patch net-phy-restore-mdio-regs-in-the-iproc-mdio-driver.patch net-sched-correct-flower-port-blocking.patch net-tls-fix-to-avoid-gettig-invalid-tls-record.patch nfc-pn544-fix-occasional-hw-initialization-failure.patch qede-fix-race-between-rdma-destroy-workqueue-and-link-change-event.patch sctp-move-the-format-error-check-out-of-__sctp_sf_do_9_1_abort.patch --- ...ags-when-splitting-a-multipath-route.patch | 49 ++++++++ ...oute-replacement-with-dev-only-route.patch | 74 ++++++++++++ ...eld-when-table-number-exceeds-8-bits.patch | 31 +++++ .../net-mscc-fix-in-frame-extraction.patch | 50 +++++++++ ...e-mdio-regs-in-the-iproc-mdio-driver.patch | 58 ++++++++++ ...t-sched-correct-flower-port-blocking.patch | 67 +++++++++++ ...x-to-avoid-gettig-invalid-tls-record.patch | 70 ++++++++++++ ...occasional-hw-initialization-failure.patch | 43 +++++++ ...troy-workqueue-and-link-change-event.patch | 106 ++++++++++++++++++ ...-check-out-of-__sctp_sf_do_9_1_abort.patch | 104 +++++++++++++++++ queue-4.19/series | 10 ++ 11 files changed, 662 insertions(+) create mode 100644 queue-4.19/ipv6-fix-nlmsg_flags-when-splitting-a-multipath-route.patch create mode 100644 queue-4.19/ipv6-fix-route-replacement-with-dev-only-route.patch create mode 100644 queue-4.19/net-fib_rules-correctly-set-table-field-when-table-number-exceeds-8-bits.patch create mode 100644 queue-4.19/net-mscc-fix-in-frame-extraction.patch create mode 100644 queue-4.19/net-phy-restore-mdio-regs-in-the-iproc-mdio-driver.patch create mode 100644 queue-4.19/net-sched-correct-flower-port-blocking.patch create mode 100644 queue-4.19/net-tls-fix-to-avoid-gettig-invalid-tls-record.patch create mode 100644 queue-4.19/nfc-pn544-fix-occasional-hw-initialization-failure.patch create mode 100644 queue-4.19/qede-fix-race-between-rdma-destroy-workqueue-and-link-change-event.patch create mode 100644 queue-4.19/sctp-move-the-format-error-check-out-of-__sctp_sf_do_9_1_abort.patch diff --git a/queue-4.19/ipv6-fix-nlmsg_flags-when-splitting-a-multipath-route.patch b/queue-4.19/ipv6-fix-nlmsg_flags-when-splitting-a-multipath-route.patch new file mode 100644 index 00000000000..b1f214f6a48 --- /dev/null +++ b/queue-4.19/ipv6-fix-nlmsg_flags-when-splitting-a-multipath-route.patch @@ -0,0 +1,49 @@ +From foo@baz Mon 02 Mar 2020 04:54:15 PM CET +From: Benjamin Poirier +Date: Wed, 12 Feb 2020 10:41:07 +0900 +Subject: ipv6: Fix nlmsg_flags when splitting a multipath route + +From: Benjamin Poirier + +[ Upstream commit afecdb376bd81d7e16578f0cfe82a1aec7ae18f3 ] + +When splitting an RTA_MULTIPATH request into multiple routes and adding the +second and later components, we must not simply remove NLM_F_REPLACE but +instead replace it by NLM_F_CREATE. Otherwise, it may look like the netlink +message was malformed. + +For example, + ip route add 2001:db8::1/128 dev dummy0 + ip route change 2001:db8::1/128 nexthop via fe80::30:1 dev dummy0 \ + nexthop via fe80::30:2 dev dummy0 +results in the following warnings: +[ 1035.057019] IPv6: RTM_NEWROUTE with no NLM_F_CREATE or NLM_F_REPLACE +[ 1035.057517] IPv6: NLM_F_CREATE should be set when creating new route + +This patch makes the nlmsg sequence look equivalent for __ip6_ins_rt() to +what it would get if the multipath route had been added in multiple netlink +operations: + ip route add 2001:db8::1/128 dev dummy0 + ip route change 2001:db8::1/128 nexthop via fe80::30:1 dev dummy0 + ip route append 2001:db8::1/128 nexthop via fe80::30:2 dev dummy0 + +Fixes: 27596472473a ("ipv6: fix ECMP route replacement") +Signed-off-by: Benjamin Poirier +Reviewed-by: Michal Kubecek +Reviewed-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/route.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -4514,6 +4514,7 @@ static int ip6_route_multipath_add(struc + */ + cfg->fc_nlinfo.nlh->nlmsg_flags &= ~(NLM_F_EXCL | + NLM_F_REPLACE); ++ cfg->fc_nlinfo.nlh->nlmsg_flags |= NLM_F_CREATE; + nhn++; + } + diff --git a/queue-4.19/ipv6-fix-route-replacement-with-dev-only-route.patch b/queue-4.19/ipv6-fix-route-replacement-with-dev-only-route.patch new file mode 100644 index 00000000000..5c75e261545 --- /dev/null +++ b/queue-4.19/ipv6-fix-route-replacement-with-dev-only-route.patch @@ -0,0 +1,74 @@ +From foo@baz Mon 02 Mar 2020 04:54:15 PM CET +From: Benjamin Poirier +Date: Wed, 12 Feb 2020 10:41:06 +0900 +Subject: ipv6: Fix route replacement with dev-only route + +From: Benjamin Poirier + +[ Upstream commit e404b8c7cfb31654c9024d497cec58a501501692 ] + +After commit 27596472473a ("ipv6: fix ECMP route replacement") it is no +longer possible to replace an ECMP-able route by a non ECMP-able route. +For example, + ip route add 2001:db8::1/128 via fe80::1 dev dummy0 + ip route replace 2001:db8::1/128 dev dummy0 +does not work as expected. + +Tweak the replacement logic so that point 3 in the log of the above commit +becomes: +3. If the new route is not ECMP-able, and no matching non-ECMP-able route +exists, replace matching ECMP-able route (if any) or add the new route. + +We can now summarize the entire replace semantics to: +When doing a replace, prefer replacing a matching route of the same +"ECMP-able-ness" as the replace argument. If there is no such candidate, +fallback to the first route found. + +Fixes: 27596472473a ("ipv6: fix ECMP route replacement") +Signed-off-by: Benjamin Poirier +Reviewed-by: Michal Kubecek +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_fib.c | 7 ++++--- + tools/testing/selftests/net/fib_tests.sh | 6 ++++++ + 2 files changed, 10 insertions(+), 3 deletions(-) + +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -981,8 +981,7 @@ static int fib6_add_rt2node(struct fib6_ + found++; + break; + } +- if (rt_can_ecmp) +- fallback_ins = fallback_ins ?: ins; ++ fallback_ins = fallback_ins ?: ins; + goto next_iter; + } + +@@ -1025,7 +1024,9 @@ next_iter: + } + + if (fallback_ins && !found) { +- /* No ECMP-able route found, replace first non-ECMP one */ ++ /* No matching route with same ecmp-able-ness found, replace ++ * first matching route ++ */ + ins = fallback_ins; + iter = rcu_dereference_protected(*ins, + lockdep_is_held(&rt->fib6_table->tb6_lock)); +--- a/tools/testing/selftests/net/fib_tests.sh ++++ b/tools/testing/selftests/net/fib_tests.sh +@@ -848,6 +848,12 @@ ipv6_rt_replace_mpath() + check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024" + log_test $? 0 "Multipath with single path via multipath attribute" + ++ # multipath with dev-only ++ add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" ++ run_cmd "$IP -6 ro replace 2001:db8:104::/64 dev veth1" ++ check_route6 "2001:db8:104::/64 dev veth1 metric 1024" ++ log_test $? 0 "Multipath with dev-only" ++ + # route replace fails - invalid nexthop 1 + add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" + run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3" diff --git a/queue-4.19/net-fib_rules-correctly-set-table-field-when-table-number-exceeds-8-bits.patch b/queue-4.19/net-fib_rules-correctly-set-table-field-when-table-number-exceeds-8-bits.patch new file mode 100644 index 00000000000..e0aad6f1c5b --- /dev/null +++ b/queue-4.19/net-fib_rules-correctly-set-table-field-when-table-number-exceeds-8-bits.patch @@ -0,0 +1,31 @@ +From foo@baz Mon 02 Mar 2020 04:54:15 PM CET +From: Jethro Beekman +Date: Wed, 12 Feb 2020 16:43:41 +0100 +Subject: net: fib_rules: Correctly set table field when table number exceeds 8 bits + +From: Jethro Beekman + +[ Upstream commit 540e585a79e9d643ede077b73bcc7aa2d7b4d919 ] + +In 709772e6e06564ed94ba740de70185ac3d792773, RT_TABLE_COMPAT was added to +allow legacy software to deal with routing table numbers >= 256, but the +same change to FIB rule queries was overlooked. + +Signed-off-by: Jethro Beekman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/fib_rules.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/core/fib_rules.c ++++ b/net/core/fib_rules.c +@@ -968,7 +968,7 @@ static int fib_nl_fill_rule(struct sk_bu + + frh = nlmsg_data(nlh); + frh->family = ops->family; +- frh->table = rule->table; ++ frh->table = rule->table < 256 ? rule->table : RT_TABLE_COMPAT; + if (nla_put_u32(skb, FRA_TABLE, rule->table)) + goto nla_put_failure; + if (nla_put_u32(skb, FRA_SUPPRESS_PREFIXLEN, rule->suppress_prefixlen)) diff --git a/queue-4.19/net-mscc-fix-in-frame-extraction.patch b/queue-4.19/net-mscc-fix-in-frame-extraction.patch new file mode 100644 index 00000000000..f832d8348b2 --- /dev/null +++ b/queue-4.19/net-mscc-fix-in-frame-extraction.patch @@ -0,0 +1,50 @@ +From foo@baz Mon 02 Mar 2020 04:54:15 PM CET +From: Horatiu Vultur +Date: Mon, 17 Feb 2020 09:31:33 +0100 +Subject: net: mscc: fix in frame extraction + +From: Horatiu Vultur + +[ Upstream commit a81541041ceb55bcec9a8bb8ad3482263f0a205a ] + +Each extracted frame on Ocelot has an IFH. The frame and IFH are extracted +by reading chuncks of 4 bytes from a register. + +In case the IFH and frames were read corretly it would try to read the next +frame. In case there are no more frames in the queue, it checks if there +were any previous errors and in that case clear the queue. But this check +will always succeed also when there are no errors. Because when extracting +the IFH the error is checked against 4(number of bytes read) and then the +error is set only if the extraction of the frame failed. So in a happy case +where there are no errors the err variable is still 4. So it could be +a case where after the check that there are no more frames in the queue, a +frame will arrive in the queue but because the error is not reseted, it +would try to flush the queue. So the frame will be lost. + +The fix consist in resetting the error after reading the IFH. + +Signed-off-by: Horatiu Vultur +Acked-by: Alexandre Belloni +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mscc/ocelot_board.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/net/ethernet/mscc/ocelot_board.c ++++ b/drivers/net/ethernet/mscc/ocelot_board.c +@@ -105,6 +105,14 @@ static irqreturn_t ocelot_xtr_irq_handle + if (err != 4) + break; + ++ /* At this point the IFH was read correctly, so it is safe to ++ * presume that there is no error. The err needs to be reset ++ * otherwise a frame could come in CPU queue between the while ++ * condition and the check for error later on. And in that case ++ * the new frame is just removed and not processed. ++ */ ++ err = 0; ++ + ocelot_parse_ifh(ifh, &info); + + dev = ocelot->ports[info.port]->dev; diff --git a/queue-4.19/net-phy-restore-mdio-regs-in-the-iproc-mdio-driver.patch b/queue-4.19/net-phy-restore-mdio-regs-in-the-iproc-mdio-driver.patch new file mode 100644 index 00000000000..242ce60a2da --- /dev/null +++ b/queue-4.19/net-phy-restore-mdio-regs-in-the-iproc-mdio-driver.patch @@ -0,0 +1,58 @@ +From foo@baz Mon 02 Mar 2020 04:54:15 PM CET +From: Arun Parameswaran +Date: Fri, 14 Feb 2020 13:47:46 -0800 +Subject: net: phy: restore mdio regs in the iproc mdio driver + +From: Arun Parameswaran + +The mii management register in iproc mdio block +does not have a retention register so it is lost on suspend. +Save and restore value of register while resuming from suspend. + +Fixes: bb1a619735b4 ("net: phy: Initialize mdio clock at probe function") +Signed-off-by: Arun Parameswaran +Signed-off-by: Scott Branden +Reviewed-by: Andrew Lunn +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/mdio-bcm-iproc.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/drivers/net/phy/mdio-bcm-iproc.c ++++ b/drivers/net/phy/mdio-bcm-iproc.c +@@ -188,6 +188,23 @@ static int iproc_mdio_remove(struct plat + return 0; + } + ++#ifdef CONFIG_PM_SLEEP ++int iproc_mdio_resume(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct iproc_mdio_priv *priv = platform_get_drvdata(pdev); ++ ++ /* restore the mii clock configuration */ ++ iproc_mdio_config_clk(priv->base); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops iproc_mdio_pm_ops = { ++ .resume = iproc_mdio_resume ++}; ++#endif /* CONFIG_PM_SLEEP */ ++ + static const struct of_device_id iproc_mdio_of_match[] = { + { .compatible = "brcm,iproc-mdio", }, + { /* sentinel */ }, +@@ -198,6 +215,9 @@ static struct platform_driver iproc_mdio + .driver = { + .name = "iproc-mdio", + .of_match_table = iproc_mdio_of_match, ++#ifdef CONFIG_PM_SLEEP ++ .pm = &iproc_mdio_pm_ops, ++#endif + }, + .probe = iproc_mdio_probe, + .remove = iproc_mdio_remove, diff --git a/queue-4.19/net-sched-correct-flower-port-blocking.patch b/queue-4.19/net-sched-correct-flower-port-blocking.patch new file mode 100644 index 00000000000..8d913faed72 --- /dev/null +++ b/queue-4.19/net-sched-correct-flower-port-blocking.patch @@ -0,0 +1,67 @@ +From foo@baz Mon 02 Mar 2020 04:54:15 PM CET +From: Jason Baron +Date: Mon, 17 Feb 2020 15:38:09 -0500 +Subject: net: sched: correct flower port blocking + +From: Jason Baron + +[ Upstream commit 8a9093c79863b58cc2f9874d7ae788f0d622a596 ] + +tc flower rules that are based on src or dst port blocking are sometimes +ineffective due to uninitialized stack data. __skb_flow_dissect() extracts +ports from the skb for tc flower to match against. However, the port +dissection is not done when when the FLOW_DIS_IS_FRAGMENT bit is set in +key_control->flags. All callers of __skb_flow_dissect(), zero-out the +key_control field except for fl_classify() as used by the flower +classifier. Thus, the FLOW_DIS_IS_FRAGMENT may be set on entry to +__skb_flow_dissect(), since key_control is allocated on the stack +and may not be initialized. + +Since key_basic and key_control are present for all flow keys, let's +make sure they are initialized. + +Fixes: 62230715fd24 ("flow_dissector: do not dissect l4 ports for fragments") +Co-developed-by: Eric Dumazet +Signed-off-by: Eric Dumazet +Acked-by: Cong Wang +Signed-off-by: Jason Baron +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/flow_dissector.h | 9 +++++++++ + net/sched/cls_flower.c | 1 + + 2 files changed, 10 insertions(+) + +--- a/include/net/flow_dissector.h ++++ b/include/net/flow_dissector.h +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + #include + + /** +@@ -306,4 +307,12 @@ static inline void *skb_flow_dissector_t + return ((char *)target_container) + flow_dissector->offset[key_id]; + } + ++static inline void ++flow_dissector_init_keys(struct flow_dissector_key_control *key_control, ++ struct flow_dissector_key_basic *key_basic) ++{ ++ memset(key_control, 0, sizeof(*key_control)); ++ memset(key_basic, 0, sizeof(*key_basic)); ++} ++ + #endif +--- a/net/sched/cls_flower.c ++++ b/net/sched/cls_flower.c +@@ -196,6 +196,7 @@ static int fl_classify(struct sk_buff *s + struct fl_flow_key skb_mkey; + + list_for_each_entry_rcu(mask, &head->masks, list) { ++ flow_dissector_init_keys(&skb_key.control, &skb_key.basic); + fl_clear_masked_range(&skb_key, mask); + + skb_key.indev_ifindex = skb->skb_iif; diff --git a/queue-4.19/net-tls-fix-to-avoid-gettig-invalid-tls-record.patch b/queue-4.19/net-tls-fix-to-avoid-gettig-invalid-tls-record.patch new file mode 100644 index 00000000000..22526ecfed9 --- /dev/null +++ b/queue-4.19/net-tls-fix-to-avoid-gettig-invalid-tls-record.patch @@ -0,0 +1,70 @@ +From foo@baz Mon 02 Mar 2020 04:54:15 PM CET +From: Rohit Maheshwari +Date: Wed, 19 Feb 2020 09:40:22 +0530 +Subject: net/tls: Fix to avoid gettig invalid tls record + +From: Rohit Maheshwari + +[ Upstream commit 06f5201c6392f998a49ca9c9173e2930c8eb51d8 ] + +Current code doesn't check if tcp sequence number is starting from (/after) +1st record's start sequnce number. It only checks if seq number is before +1st record's end sequnce number. This problem will always be a possibility +in re-transmit case. If a record which belongs to a requested seq number is +already deleted, tls_get_record will start looking into list and as per the +check it will look if seq number is before the end seq of 1st record, which +will always be true and will return 1st record always, it should in fact +return NULL. +As part of the fix, start looking each record only if the sequence number +lies in the list else return NULL. +There is one more check added, driver look for the start marker record to +handle tcp packets which are before the tls offload start sequence number, +hence return 1st record if the record is tls start marker and seq number is +before the 1st record's starting sequence number. + +Fixes: e8f69799810c ("net/tls: Add generic NIC offload infrastructure") +Signed-off-by: Rohit Maheshwari +Reviewed-by: Jakub Kicinski +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tls/tls_device.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +--- a/net/tls/tls_device.c ++++ b/net/tls/tls_device.c +@@ -506,7 +506,7 @@ struct tls_record_info *tls_get_record(s + u32 seq, u64 *p_record_sn) + { + u64 record_sn = context->hint_record_sn; +- struct tls_record_info *info; ++ struct tls_record_info *info, *last; + + info = context->retransmit_hint; + if (!info || +@@ -516,6 +516,25 @@ struct tls_record_info *tls_get_record(s + */ + info = list_first_entry(&context->records_list, + struct tls_record_info, list); ++ ++ /* send the start_marker record if seq number is before the ++ * tls offload start marker sequence number. This record is ++ * required to handle TCP packets which are before TLS offload ++ * started. ++ * And if it's not start marker, look if this seq number ++ * belongs to the list. ++ */ ++ if (likely(!tls_record_is_start_marker(info))) { ++ /* we have the first record, get the last record to see ++ * if this seq number belongs to the list. ++ */ ++ last = list_last_entry(&context->records_list, ++ struct tls_record_info, list); ++ ++ if (!between(seq, tls_record_start_seq(info), ++ last->end_seq)) ++ return NULL; ++ } + record_sn = context->unacked_record_sn; + } + diff --git a/queue-4.19/nfc-pn544-fix-occasional-hw-initialization-failure.patch b/queue-4.19/nfc-pn544-fix-occasional-hw-initialization-failure.patch new file mode 100644 index 00000000000..dc3acb07087 --- /dev/null +++ b/queue-4.19/nfc-pn544-fix-occasional-hw-initialization-failure.patch @@ -0,0 +1,43 @@ +From foo@baz Mon 02 Mar 2020 04:54:15 PM CET +From: Dmitry Osipenko +Date: Wed, 19 Feb 2020 18:01:22 +0300 +Subject: nfc: pn544: Fix occasional HW initialization failure + +From: Dmitry Osipenko + +[ Upstream commit c3331d2fe3fd4d5e321f2467d01f72de7edfb5d0 ] + +The PN544 driver checks the "enable" polarity during of driver's probe and +it's doing that by turning ON and OFF NFC with different polarities until +enabling succeeds. It takes some time for the hardware to power-down, and +thus, to deassert the IRQ that is raised by turning ON the hardware. +Since the delay after last power-down of the polarity-checking process is +missed in the code, the interrupt may trigger immediately after installing +the IRQ handler (right after the checking is done), which results in IRQ +handler trying to touch the disabled HW and ends with marking NFC as +'DEAD' during of the driver's probe: + + pn544_hci_i2c 1-002a: NFC: nfc_en polarity : active high + pn544_hci_i2c 1-002a: NFC: invalid len byte + shdlc: llc_shdlc_recv_frame: NULL Frame -> link is dead + +This patch fixes the occasional NFC initialization failure on Nexus 7 +device. + +Signed-off-by: Dmitry Osipenko +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nfc/pn544/i2c.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/nfc/pn544/i2c.c ++++ b/drivers/nfc/pn544/i2c.c +@@ -236,6 +236,7 @@ static void pn544_hci_i2c_platform_init( + + out: + gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity); ++ usleep_range(10000, 15000); + } + + static void pn544_hci_i2c_enable_mode(struct pn544_i2c_phy *phy, int run_mode) diff --git a/queue-4.19/qede-fix-race-between-rdma-destroy-workqueue-and-link-change-event.patch b/queue-4.19/qede-fix-race-between-rdma-destroy-workqueue-and-link-change-event.patch new file mode 100644 index 00000000000..bdb948b7743 --- /dev/null +++ b/queue-4.19/qede-fix-race-between-rdma-destroy-workqueue-and-link-change-event.patch @@ -0,0 +1,106 @@ +From foo@baz Mon 02 Mar 2020 04:54:15 PM CET +From: Michal Kalderon +Date: Mon, 17 Feb 2020 13:37:18 +0200 +Subject: qede: Fix race between rdma destroy workqueue and link change event + +From: Michal Kalderon + +[ Upstream commit af6565adb02d3129d3fae4d9d5da945abaf4417a ] + +If an event is added while the rdma workqueue is being destroyed +it could lead to several races, list corruption, null pointer +dereference during queue_work or init_queue. +This fixes the race between the two flows which can occur during +shutdown. + +A kref object and a completion object are added to the rdma_dev +structure, these are initialized before the workqueue is created. +The refcnt is used to indicate work is being added to the +workqueue and ensures the cleanup flow won't start while we're in +the middle of adding the event. +Once the work is added, the refcnt is decreased and the cleanup flow +is safe to run. + +Fixes: cee9fbd8e2e ("qede: Add qedr framework") +Signed-off-by: Ariel Elior +Signed-off-by: Michal Kalderon +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/qlogic/qede/qede.h | 2 + + drivers/net/ethernet/qlogic/qede/qede_rdma.c | 29 ++++++++++++++++++++++++++- + 2 files changed, 30 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/qlogic/qede/qede.h ++++ b/drivers/net/ethernet/qlogic/qede/qede.h +@@ -162,6 +162,8 @@ struct qede_rdma_dev { + struct list_head entry; + struct list_head rdma_event_list; + struct workqueue_struct *rdma_wq; ++ struct kref refcnt; ++ struct completion event_comp; + }; + + struct qede_ptp; +--- a/drivers/net/ethernet/qlogic/qede/qede_rdma.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_rdma.c +@@ -57,6 +57,9 @@ static void _qede_rdma_dev_add(struct qe + static int qede_rdma_create_wq(struct qede_dev *edev) + { + INIT_LIST_HEAD(&edev->rdma_info.rdma_event_list); ++ kref_init(&edev->rdma_info.refcnt); ++ init_completion(&edev->rdma_info.event_comp); ++ + edev->rdma_info.rdma_wq = create_singlethread_workqueue("rdma_wq"); + if (!edev->rdma_info.rdma_wq) { + DP_NOTICE(edev, "qedr: Could not create workqueue\n"); +@@ -81,8 +84,23 @@ static void qede_rdma_cleanup_event(stru + } + } + ++static void qede_rdma_complete_event(struct kref *ref) ++{ ++ struct qede_rdma_dev *rdma_dev = ++ container_of(ref, struct qede_rdma_dev, refcnt); ++ ++ /* no more events will be added after this */ ++ complete(&rdma_dev->event_comp); ++} ++ + static void qede_rdma_destroy_wq(struct qede_dev *edev) + { ++ /* Avoid race with add_event flow, make sure it finishes before ++ * we start accessing the list and cleaning up the work ++ */ ++ kref_put(&edev->rdma_info.refcnt, qede_rdma_complete_event); ++ wait_for_completion(&edev->rdma_info.event_comp); ++ + qede_rdma_cleanup_event(edev); + destroy_workqueue(edev->rdma_info.rdma_wq); + } +@@ -287,15 +305,24 @@ static void qede_rdma_add_event(struct q + if (!edev->rdma_info.qedr_dev) + return; + ++ /* We don't want the cleanup flow to start while we're allocating and ++ * scheduling the work ++ */ ++ if (!kref_get_unless_zero(&edev->rdma_info.refcnt)) ++ return; /* already being destroyed */ ++ + event_node = qede_rdma_get_free_event_node(edev); + if (!event_node) +- return; ++ goto out; + + event_node->event = event; + event_node->ptr = edev; + + INIT_WORK(&event_node->work, qede_rdma_handle_event); + queue_work(edev->rdma_info.rdma_wq, &event_node->work); ++ ++out: ++ kref_put(&edev->rdma_info.refcnt, qede_rdma_complete_event); + } + + void qede_rdma_dev_event_open(struct qede_dev *edev) diff --git a/queue-4.19/sctp-move-the-format-error-check-out-of-__sctp_sf_do_9_1_abort.patch b/queue-4.19/sctp-move-the-format-error-check-out-of-__sctp_sf_do_9_1_abort.patch new file mode 100644 index 00000000000..8e12192b451 --- /dev/null +++ b/queue-4.19/sctp-move-the-format-error-check-out-of-__sctp_sf_do_9_1_abort.patch @@ -0,0 +1,104 @@ +From foo@baz Mon 02 Mar 2020 04:54:15 PM CET +From: Xin Long +Date: Tue, 18 Feb 2020 12:07:53 +0800 +Subject: sctp: move the format error check out of __sctp_sf_do_9_1_abort + +From: Xin Long + +[ Upstream commit 245709ec8be89af46ea7ef0444c9c80913999d99 ] + +When T2 timer is to be stopped, the asoc should also be deleted, +otherwise, there will be no chance to call sctp_association_free +and the asoc could last in memory forever. + +However, in sctp_sf_shutdown_sent_abort(), after adding the cmd +SCTP_CMD_TIMER_STOP for T2 timer, it may return error due to the +format error from __sctp_sf_do_9_1_abort() and miss adding +SCTP_CMD_ASSOC_FAILED where the asoc will be deleted. + +This patch is to fix it by moving the format error check out of +__sctp_sf_do_9_1_abort(), and do it before adding the cmd +SCTP_CMD_TIMER_STOP for T2 timer. + +Thanks Hangbin for reporting this issue by the fuzz testing. + +v1->v2: + - improve the comment in the code as Marcelo's suggestion. + +Fixes: 96ca468b86b0 ("sctp: check invalid value of length parameter in error cause") +Reported-by: Hangbin Liu +Acked-by: Marcelo Ricardo Leitner +Signed-off-by: Xin Long +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/sm_statefuns.c | 29 ++++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -185,6 +185,16 @@ static inline bool sctp_chunk_length_val + return true; + } + ++/* Check for format error in an ABORT chunk */ ++static inline bool sctp_err_chunk_valid(struct sctp_chunk *chunk) ++{ ++ struct sctp_errhdr *err; ++ ++ sctp_walk_errors(err, chunk->chunk_hdr); ++ ++ return (void *)err == (void *)chunk->chunk_end; ++} ++ + /********************************************************** + * These are the state functions for handling chunk events. + **********************************************************/ +@@ -2270,6 +2280,9 @@ enum sctp_disposition sctp_sf_shutdown_p + sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) + return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands); + ++ if (!sctp_err_chunk_valid(chunk)) ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); ++ + return __sctp_sf_do_9_1_abort(net, ep, asoc, type, arg, commands); + } + +@@ -2313,6 +2326,9 @@ enum sctp_disposition sctp_sf_shutdown_s + sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) + return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands); + ++ if (!sctp_err_chunk_valid(chunk)) ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); ++ + /* Stop the T2-shutdown timer. */ + sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, + SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); +@@ -2580,6 +2596,9 @@ enum sctp_disposition sctp_sf_do_9_1_abo + sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) + return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands); + ++ if (!sctp_err_chunk_valid(chunk)) ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); ++ + return __sctp_sf_do_9_1_abort(net, ep, asoc, type, arg, commands); + } + +@@ -2597,16 +2616,8 @@ static enum sctp_disposition __sctp_sf_d + + /* See if we have an error cause code in the chunk. */ + len = ntohs(chunk->chunk_hdr->length); +- if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) { +- struct sctp_errhdr *err; +- +- sctp_walk_errors(err, chunk->chunk_hdr); +- if ((void *)err != (void *)chunk->chunk_end) +- return sctp_sf_pdiscard(net, ep, asoc, type, arg, +- commands); +- ++ if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) + error = ((struct sctp_errhdr *)chunk->skb->data)->cause; +- } + + sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET)); + /* ASSOC_FAILED will DELETE_TCB. */ diff --git a/queue-4.19/series b/queue-4.19/series index 300a5a386f6..1b2c5726143 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -26,3 +26,13 @@ bcache-ignore-pending-signals-when-creating-gc-and-a.patch cfg80211-add-missing-policy-for-nl80211_attr_status_.patch sysrq-restore-original-console_loglevel-when-sysrq-disabled.patch sysrq-remove-duplicated-sysrq-message.patch +net-fib_rules-correctly-set-table-field-when-table-number-exceeds-8-bits.patch +net-mscc-fix-in-frame-extraction.patch +net-phy-restore-mdio-regs-in-the-iproc-mdio-driver.patch +net-sched-correct-flower-port-blocking.patch +nfc-pn544-fix-occasional-hw-initialization-failure.patch +sctp-move-the-format-error-check-out-of-__sctp_sf_do_9_1_abort.patch +ipv6-fix-route-replacement-with-dev-only-route.patch +ipv6-fix-nlmsg_flags-when-splitting-a-multipath-route.patch +qede-fix-race-between-rdma-destroy-workqueue-and-link-change-event.patch +net-tls-fix-to-avoid-gettig-invalid-tls-record.patch -- 2.47.3