From: Greg Kroah-Hartman Date: Fri, 25 Sep 2020 09:13:03 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v4.19.148~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=54393621eb2aa8995c36963f55b3d116baff591e;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: bnxt_en-protect-bnxt_set_eee-and-bnxt_set_pauseparam-with-mutex.patch hdlc_ppp-add-range-checks-in-ppp_cp_parse_cr.patch ip-fix-tos-reflection-in-ack-and-reset-packets.patch net-add-__must_check-to-skb_put_padto.patch net-hsr-check-skb_put_padto-return-value.patch net-phy-avoid-npd-upon-phy_detach-when-driver-is-unbound.patch tipc-use-skb_unshare-instead-in-tipc_buf_append.patch --- diff --git a/queue-4.9/bnxt_en-protect-bnxt_set_eee-and-bnxt_set_pauseparam-with-mutex.patch b/queue-4.9/bnxt_en-protect-bnxt_set_eee-and-bnxt_set_pauseparam-with-mutex.patch new file mode 100644 index 00000000000..277563fff78 --- /dev/null +++ b/queue-4.9/bnxt_en-protect-bnxt_set_eee-and-bnxt_set_pauseparam-with-mutex.patch @@ -0,0 +1,109 @@ +From foo@baz Fri Sep 25 11:00:38 AM CEST 2020 +From: Michael Chan +Date: Sun, 20 Sep 2020 21:08:56 -0400 +Subject: bnxt_en: Protect bnxt_set_eee() and bnxt_set_pauseparam() with mutex. + +From: Michael Chan + +[ Upstream commit a53906908148d64423398a62c4435efb0d09652c ] + +All changes related to bp->link_info require the protection of the +link_lock mutex. It's not sufficient to rely just on RTNL. + +Fixes: 163e9ef63641 ("bnxt_en: Fix race when modifying pause settings.") +Reviewed-by: Edwin Peer +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 31 ++++++++++++++-------- + 1 file changed, 20 insertions(+), 11 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +@@ -1000,9 +1000,12 @@ static int bnxt_set_pauseparam(struct ne + if (!BNXT_SINGLE_PF(bp)) + return -EOPNOTSUPP; + ++ mutex_lock(&bp->link_lock); + if (epause->autoneg) { +- if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) +- return -EINVAL; ++ if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) { ++ rc = -EINVAL; ++ goto pause_exit; ++ } + + link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL; + if (bp->hwrm_spec_code >= 0x10201) +@@ -1023,11 +1026,11 @@ static int bnxt_set_pauseparam(struct ne + if (epause->tx_pause) + link_info->req_flow_ctrl |= BNXT_LINK_PAUSE_TX; + +- if (netif_running(dev)) { +- mutex_lock(&bp->link_lock); ++ if (netif_running(dev)) + rc = bnxt_hwrm_set_pause(bp); +- mutex_unlock(&bp->link_lock); +- } ++ ++pause_exit: ++ mutex_unlock(&bp->link_lock); + return rc; + } + +@@ -1671,8 +1674,7 @@ static int bnxt_set_eee(struct net_devic + struct bnxt *bp = netdev_priv(dev); + struct ethtool_eee *eee = &bp->eee; + struct bnxt_link_info *link_info = &bp->link_info; +- u32 advertising = +- _bnxt_fw_to_ethtool_adv_spds(link_info->advertising, 0); ++ u32 advertising; + int rc = 0; + + if (!BNXT_SINGLE_PF(bp)) +@@ -1681,19 +1683,23 @@ static int bnxt_set_eee(struct net_devic + if (!(bp->flags & BNXT_FLAG_EEE_CAP)) + return -EOPNOTSUPP; + ++ mutex_lock(&bp->link_lock); ++ advertising = _bnxt_fw_to_ethtool_adv_spds(link_info->advertising, 0); + if (!edata->eee_enabled) + goto eee_ok; + + if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) { + netdev_warn(dev, "EEE requires autoneg\n"); +- return -EINVAL; ++ rc = -EINVAL; ++ goto eee_exit; + } + if (edata->tx_lpi_enabled) { + if (bp->lpi_tmr_hi && (edata->tx_lpi_timer > bp->lpi_tmr_hi || + edata->tx_lpi_timer < bp->lpi_tmr_lo)) { + netdev_warn(dev, "Valid LPI timer range is %d and %d microsecs\n", + bp->lpi_tmr_lo, bp->lpi_tmr_hi); +- return -EINVAL; ++ rc = -EINVAL; ++ goto eee_exit; + } else if (!bp->lpi_tmr_hi) { + edata->tx_lpi_timer = eee->tx_lpi_timer; + } +@@ -1703,7 +1709,8 @@ static int bnxt_set_eee(struct net_devic + } else if (edata->advertised & ~advertising) { + netdev_warn(dev, "EEE advertised %x must be a subset of autoneg advertised speeds %x\n", + edata->advertised, advertising); +- return -EINVAL; ++ rc = -EINVAL; ++ goto eee_exit; + } + + eee->advertised = edata->advertised; +@@ -1715,6 +1722,8 @@ eee_ok: + if (netif_running(dev)) + rc = bnxt_hwrm_set_link_setting(bp, false, true); + ++eee_exit: ++ mutex_unlock(&bp->link_lock); + return rc; + } + diff --git a/queue-4.9/hdlc_ppp-add-range-checks-in-ppp_cp_parse_cr.patch b/queue-4.9/hdlc_ppp-add-range-checks-in-ppp_cp_parse_cr.patch new file mode 100644 index 00000000000..f1ae4405064 --- /dev/null +++ b/queue-4.9/hdlc_ppp-add-range-checks-in-ppp_cp_parse_cr.patch @@ -0,0 +1,80 @@ +From foo@baz Fri Sep 25 11:00:38 AM CEST 2020 +From: Dan Carpenter +Date: Wed, 9 Sep 2020 12:46:48 +0300 +Subject: hdlc_ppp: add range checks in ppp_cp_parse_cr() + +From: Dan Carpenter + +[ Upstream commit 66d42ed8b25b64eb63111a2b8582c5afc8bf1105 ] + +There are a couple bugs here: +1) If opt[1] is zero then this results in a forever loop. If the value + is less than 2 then it is invalid. +2) It assumes that "len" is more than sizeof(valid_accm) or 6 which can + result in memory corruption. + +In the case of LCP_OPTION_ACCM, then we should check "opt[1]" instead +of "len" because, if "opt[1]" is less than sizeof(valid_accm) then +"nak_len" gets out of sync and it can lead to memory corruption in the +next iterations through the loop. In case of LCP_OPTION_MAGIC, the +only valid value for opt[1] is 6, but the code is trying to log invalid +data so we should only discard the data when "len" is less than 6 +because that leads to a read overflow. + +Reported-by: ChenNan Of Chaitin Security Research Lab +Fixes: e022c2f07ae5 ("WAN: new synchronous PPP implementation for generic HDLC.") +Signed-off-by: Dan Carpenter +Reviewed-by: Eric Dumazet +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wan/hdlc_ppp.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +--- a/drivers/net/wan/hdlc_ppp.c ++++ b/drivers/net/wan/hdlc_ppp.c +@@ -386,11 +386,8 @@ static void ppp_cp_parse_cr(struct net_d + } + + for (opt = data; len; len -= opt[1], opt += opt[1]) { +- if (len < 2 || len < opt[1]) { +- dev->stats.rx_errors++; +- kfree(out); +- return; /* bad packet, drop silently */ +- } ++ if (len < 2 || opt[1] < 2 || len < opt[1]) ++ goto err_out; + + if (pid == PID_LCP) + switch (opt[0]) { +@@ -398,6 +395,8 @@ static void ppp_cp_parse_cr(struct net_d + continue; /* MRU always OK and > 1500 bytes? */ + + case LCP_OPTION_ACCM: /* async control character map */ ++ if (opt[1] < sizeof(valid_accm)) ++ goto err_out; + if (!memcmp(opt, valid_accm, + sizeof(valid_accm))) + continue; +@@ -409,6 +408,8 @@ static void ppp_cp_parse_cr(struct net_d + } + break; + case LCP_OPTION_MAGIC: ++ if (len < 6) ++ goto err_out; + if (opt[1] != 6 || (!opt[2] && !opt[3] && + !opt[4] && !opt[5])) + break; /* reject invalid magic number */ +@@ -427,6 +428,11 @@ static void ppp_cp_parse_cr(struct net_d + ppp_cp_event(dev, pid, RCR_GOOD, CP_CONF_ACK, id, req_len, data); + + kfree(out); ++ return; ++ ++err_out: ++ dev->stats.rx_errors++; ++ kfree(out); + } + + static int ppp_rx(struct sk_buff *skb) diff --git a/queue-4.9/ip-fix-tos-reflection-in-ack-and-reset-packets.patch b/queue-4.9/ip-fix-tos-reflection-in-ack-and-reset-packets.patch new file mode 100644 index 00000000000..7c8730798d0 --- /dev/null +++ b/queue-4.9/ip-fix-tos-reflection-in-ack-and-reset-packets.patch @@ -0,0 +1,43 @@ +From foo@baz Fri Sep 25 11:00:38 AM CEST 2020 +From: Wei Wang +Date: Tue, 8 Sep 2020 14:09:34 -0700 +Subject: ip: fix tos reflection in ack and reset packets + +From: Wei Wang + +[ Upstream commit ba9e04a7ddf4f22a10e05bf9403db6b97743c7bf ] + +Currently, in tcp_v4_reqsk_send_ack() and tcp_v4_send_reset(), we +echo the TOS value of the received packets in the response. +However, we do not want to echo the lower 2 ECN bits in accordance +with RFC 3168 6.1.5 robustness principles. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") + +Signed-off-by: Wei Wang +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_output.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -73,6 +73,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1611,7 +1612,7 @@ void ip_send_unicast_reply(struct sock * + if (IS_ERR(rt)) + return; + +- inet_sk(sk)->tos = arg->tos; ++ inet_sk(sk)->tos = arg->tos & ~INET_ECN_MASK; + + sk->sk_priority = skb->priority; + sk->sk_protocol = ip_hdr(skb)->protocol; diff --git a/queue-4.9/mtd-fix-comparison-in-map_word_andequal.patch b/queue-4.9/mtd-fix-comparison-in-map_word_andequal.patch index deab24e8d49..483ea6949dd 100644 --- a/queue-4.9/mtd-fix-comparison-in-map_word_andequal.patch +++ b/queue-4.9/mtd-fix-comparison-in-map_word_andequal.patch @@ -21,11 +21,9 @@ Signed-off-by: Boris Brezillon Signed-off-by: Nobuhiro Iwamatsu (CIP) Signed-off-by: Sasha Levin --- - include/linux/mtd/map.h | 2 +- + include/linux/mtd/map.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h -index b5b43f94f3116..01b990e4b228a 100644 --- a/include/linux/mtd/map.h +++ b/include/linux/mtd/map.h @@ -312,7 +312,7 @@ void map_destroy(struct mtd_info *mtd); @@ -37,6 +35,3 @@ index b5b43f94f3116..01b990e4b228a 100644 ret = 0; \ break; \ } \ --- -2.25.1 - diff --git a/queue-4.9/net-add-__must_check-to-skb_put_padto.patch b/queue-4.9/net-add-__must_check-to-skb_put_padto.patch new file mode 100644 index 00000000000..25a63e2177c --- /dev/null +++ b/queue-4.9/net-add-__must_check-to-skb_put_padto.patch @@ -0,0 +1,30 @@ +From foo@baz Fri Sep 25 11:00:38 AM CEST 2020 +From: Eric Dumazet +Date: Wed, 9 Sep 2020 01:27:40 -0700 +Subject: net: add __must_check to skb_put_padto() + +From: Eric Dumazet + +[ Upstream commit 4a009cb04aeca0de60b73f37b102573354214b52 ] + +skb_put_padto() and __skb_put_padto() callers +must check return values or risk use-after-free. + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/skbuff.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -2795,7 +2795,7 @@ static inline int skb_padto(struct sk_bu + * is untouched. Otherwise it is extended. Returns zero on + * success. The skb is freed on error. + */ +-static inline int skb_put_padto(struct sk_buff *skb, unsigned int len) ++static inline int __must_check skb_put_padto(struct sk_buff *skb, unsigned int len) + { + unsigned int size = skb->len; + diff --git a/queue-4.9/net-hsr-check-skb_put_padto-return-value.patch b/queue-4.9/net-hsr-check-skb_put_padto-return-value.patch new file mode 100644 index 00000000000..2d493430336 --- /dev/null +++ b/queue-4.9/net-hsr-check-skb_put_padto-return-value.patch @@ -0,0 +1,36 @@ +From 414e7d76af6d3ec2dd4e9079927dbe0e2e4ca914 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli +Date: Mon, 21 Aug 2017 12:59:10 -0700 +Subject: net/hsr: Check skb_put_padto() return value + +From: Florian Fainelli + +commit 414e7d76af6d3ec2dd4e9079927dbe0e2e4ca914 upstream. + +skb_put_padto() will free the sk_buff passed as reference in case of +errors, but we still need to check its return value and decide what to +do. + +Detected by CoverityScan, CID#1416688 ("CHECKED_RETURN") + +Fixes: ee1c27977284 ("net/hsr: Added support for HSR v1") +Signed-off-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/hsr/hsr_device.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/hsr/hsr_device.c ++++ b/net/hsr/hsr_device.c +@@ -315,7 +315,8 @@ static void send_hsr_supervision_frame(s + hsr_sp = (typeof(hsr_sp)) skb_put(skb, sizeof(struct hsr_sup_payload)); + ether_addr_copy(hsr_sp->MacAddressA, master->dev->dev_addr); + +- skb_put_padto(skb, ETH_ZLEN + HSR_HLEN); ++ if (skb_put_padto(skb, ETH_ZLEN + HSR_HLEN)) ++ return; + + hsr_forward_skb(skb, master); + return; diff --git a/queue-4.9/net-phy-avoid-npd-upon-phy_detach-when-driver-is-unbound.patch b/queue-4.9/net-phy-avoid-npd-upon-phy_detach-when-driver-is-unbound.patch new file mode 100644 index 00000000000..76355961f46 --- /dev/null +++ b/queue-4.9/net-phy-avoid-npd-upon-phy_detach-when-driver-is-unbound.patch @@ -0,0 +1,37 @@ +From foo@baz Fri Sep 25 11:00:38 AM CEST 2020 +From: Florian Fainelli +Date: Wed, 16 Sep 2020 20:43:09 -0700 +Subject: net: phy: Avoid NPD upon phy_detach() when driver is unbound + +From: Florian Fainelli + +[ Upstream commit c2b727df7caa33876e7066bde090f40001b6d643 ] + +If we have unbound the PHY driver prior to calling phy_detach() (often +via phy_disconnect()) then we can cause a NULL pointer de-reference +accessing the driver owner member. The steps to reproduce are: + +echo unimac-mdio-0:01 > /sys/class/net/eth0/phydev/driver/unbind +ip link set eth0 down + +Fixes: cafe8df8b9bc ("net: phy: Fix lack of reference count on PHY driver") +Signed-off-by: Florian Fainelli +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/phy_device.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -1013,7 +1013,8 @@ void phy_detach(struct phy_device *phyde + phydev->attached_dev = NULL; + phy_suspend(phydev); + +- module_put(phydev->mdio.dev.driver->owner); ++ if (phydev->mdio.dev.driver) ++ module_put(phydev->mdio.dev.driver->owner); + + /* If the device had no specific driver before (i.e. - it + * was using the generic driver), we unbind the device diff --git a/queue-4.9/series b/queue-4.9/series index b3162062e6a..02136379462 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -3,3 +3,10 @@ kvm-fix-memory-leak-in-kvm_io_bus_unregister_dev.patch kprobes-fix-kill-kprobe-which-has-been-marked-as-gon.patch rdma-ucma-ucma_context-reference-leak-in-error-path.patch mtd-fix-comparison-in-map_word_andequal.patch +hdlc_ppp-add-range-checks-in-ppp_cp_parse_cr.patch +ip-fix-tos-reflection-in-ack-and-reset-packets.patch +tipc-use-skb_unshare-instead-in-tipc_buf_append.patch +bnxt_en-protect-bnxt_set_eee-and-bnxt_set_pauseparam-with-mutex.patch +net-phy-avoid-npd-upon-phy_detach-when-driver-is-unbound.patch +net-hsr-check-skb_put_padto-return-value.patch +net-add-__must_check-to-skb_put_padto.patch diff --git a/queue-4.9/tipc-use-skb_unshare-instead-in-tipc_buf_append.patch b/queue-4.9/tipc-use-skb_unshare-instead-in-tipc_buf_append.patch new file mode 100644 index 00000000000..4f2b165604b --- /dev/null +++ b/queue-4.9/tipc-use-skb_unshare-instead-in-tipc_buf_append.patch @@ -0,0 +1,67 @@ +From foo@baz Fri Sep 25 11:00:38 AM CEST 2020 +From: Xin Long +Date: Sun, 13 Sep 2020 19:37:31 +0800 +Subject: tipc: use skb_unshare() instead in tipc_buf_append() + +From: Xin Long + +[ Upstream commit ff48b6222e65ebdba5a403ef1deba6214e749193 ] + +In tipc_buf_append() it may change skb's frag_list, and it causes +problems when this skb is cloned. skb_unclone() doesn't really +make this skb's flag_list available to change. + +Shuang Li has reported an use-after-free issue because of this +when creating quite a few macvlan dev over the same dev, where +the broadcast packets will be cloned and go up to the stack: + + [ ] BUG: KASAN: use-after-free in pskb_expand_head+0x86d/0xea0 + [ ] Call Trace: + [ ] dump_stack+0x7c/0xb0 + [ ] print_address_description.constprop.7+0x1a/0x220 + [ ] kasan_report.cold.10+0x37/0x7c + [ ] check_memory_region+0x183/0x1e0 + [ ] pskb_expand_head+0x86d/0xea0 + [ ] process_backlog+0x1df/0x660 + [ ] net_rx_action+0x3b4/0xc90 + [ ] + [ ] Allocated by task 1786: + [ ] kmem_cache_alloc+0xbf/0x220 + [ ] skb_clone+0x10a/0x300 + [ ] macvlan_broadcast+0x2f6/0x590 [macvlan] + [ ] macvlan_process_broadcast+0x37c/0x516 [macvlan] + [ ] process_one_work+0x66a/0x1060 + [ ] worker_thread+0x87/0xb10 + [ ] + [ ] Freed by task 3253: + [ ] kmem_cache_free+0x82/0x2a0 + [ ] skb_release_data+0x2c3/0x6e0 + [ ] kfree_skb+0x78/0x1d0 + [ ] tipc_recvmsg+0x3be/0xa40 [tipc] + +So fix it by using skb_unshare() instead, which would create a new +skb for the cloned frag and it'll be safe to change its frag_list. +The similar things were also done in sctp_make_reassembled_event(), +which is using skb_copy(). + +Reported-by: Shuang Li +Fixes: 37e22164a8a3 ("tipc: rename and move message reassembly function") +Signed-off-by: Xin Long +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tipc/msg.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/tipc/msg.c ++++ b/net/tipc/msg.c +@@ -140,7 +140,8 @@ int tipc_buf_append(struct sk_buff **hea + if (fragid == FIRST_FRAGMENT) { + if (unlikely(head)) + goto err; +- if (unlikely(skb_unclone(frag, GFP_ATOMIC))) ++ frag = skb_unshare(frag, GFP_ATOMIC); ++ if (unlikely(!frag)) + goto err; + head = *headbuf = frag; + *buf = NULL;