From: Greg Kroah-Hartman Date: Sat, 4 May 2019 07:24:41 +0000 (+0200) Subject: 5.0-stable patches X-Git-Tag: v4.19.40~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=62d56e2fb7e541a08781488bfc39e5f4cb0261ab;p=thirdparty%2Fkernel%2Fstable-queue.git 5.0-stable patches added patches: bnxt_en-fix-possible-crash-in-bnxt_hwrm_ring_free-under-error-conditions.patch bnxt_en-fix-statistics-context-reservation-logic.patch bnxt_en-fix-uninitialized-variable-usage-in-bnxt_rx_pkt.patch bnxt_en-free-short-fw-command-hwrm-memory-in-error-path-in-bnxt_init_one.patch bnxt_en-improve-multicast-address-setup-logic.patch bnxt_en-pass-correct-extended-tx-port-statistics-size-to-firmware.patch ipv4-ip_do_fragment-preserve-skb_iif-during-fragmentation.patch ipv6-a-few-fixes-on-dereferencing-rt-from.patch ipv6-fix-races-in-ip6_dst_destroy.patch ipv6-flowlabel-wait-rcu-grace-period-before-put_pid.patch ipv6-invert-flowlabel-sharing-check-in-process-and-user-mode.patch l2ip-fix-possible-use-after-free.patch l2tp-use-rcu_dereference_sk_user_data-in-l2tp_udp_encap_recv.patch net-dsa-bcm_sf2-fix-buffer-overflow-doing-set_rxnfc.patch net-phy-marvell-fix-buffer-overrun-with-stats-counters.patch net-tls-avoid-null-pointer-deref-on-nskb-sk-in-fallback.patch net-tls-don-t-copy-negative-amounts-of-data-in-reencrypt.patch net-tls-fix-copy-to-fragments-in-reencrypt.patch packet-in-recvmsg-msg_name-return-at-least-sizeof-sockaddr_ll.patch packet-validate-msg_namelen-in-send-directly.patch rxrpc-fix-net-namespace-cleanup.patch sctp-avoid-running-the-sctp-state-machine-recursively.patch selftests-fib_rule_tests-fix-icmp-proto-with-ipv6.patch selftests-fib_rule_tests-print-the-result-and-return-1-if-any-tests-failed.patch tcp-add-sanity-tests-in-tcp_add_backlog.patch udp-fix-gro-packet-of-death.patch udp-fix-gro-reception-in-case-of-length-mismatch.patch --- diff --git a/queue-5.0/bnxt_en-fix-possible-crash-in-bnxt_hwrm_ring_free-under-error-conditions.patch b/queue-5.0/bnxt_en-fix-possible-crash-in-bnxt_hwrm_ring_free-under-error-conditions.patch new file mode 100644 index 00000000000..41357cf313f --- /dev/null +++ b/queue-5.0/bnxt_en-fix-possible-crash-in-bnxt_hwrm_ring_free-under-error-conditions.patch @@ -0,0 +1,66 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Michael Chan +Date: Thu, 25 Apr 2019 22:31:52 -0400 +Subject: bnxt_en: Fix possible crash in bnxt_hwrm_ring_free() under error conditions. + +From: Michael Chan + +[ Upstream commit 1f83391bd6fc48f92f627b0ec0bce686d100c6a5 ] + +If we encounter errors during open and proceed to clean up, +bnxt_hwrm_ring_free() may crash if the rings we try to free have never +been allocated. bnxt_cp_ring_for_rx() or bnxt_cp_ring_for_tx() +may reference pointers that have not been allocated. + +Fix it by checking for valid fw_ring_id first before calling +bnxt_cp_ring_for_rx() or bnxt_cp_ring_for_tx(). + +Fixes: 2c61d2117ecb ("bnxt_en: Add helper functions to get firmware CP ring ID.") +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -5131,10 +5131,10 @@ static void bnxt_hwrm_ring_free(struct b + for (i = 0; i < bp->tx_nr_rings; i++) { + struct bnxt_tx_ring_info *txr = &bp->tx_ring[i]; + struct bnxt_ring_struct *ring = &txr->tx_ring_struct; +- u32 cmpl_ring_id; + +- cmpl_ring_id = bnxt_cp_ring_for_tx(bp, txr); + if (ring->fw_ring_id != INVALID_HW_RING_ID) { ++ u32 cmpl_ring_id = bnxt_cp_ring_for_tx(bp, txr); ++ + hwrm_ring_free_send_msg(bp, ring, + RING_FREE_REQ_RING_TYPE_TX, + close_path ? cmpl_ring_id : +@@ -5147,10 +5147,10 @@ static void bnxt_hwrm_ring_free(struct b + struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i]; + struct bnxt_ring_struct *ring = &rxr->rx_ring_struct; + u32 grp_idx = rxr->bnapi->index; +- u32 cmpl_ring_id; + +- cmpl_ring_id = bnxt_cp_ring_for_rx(bp, rxr); + if (ring->fw_ring_id != INVALID_HW_RING_ID) { ++ u32 cmpl_ring_id = bnxt_cp_ring_for_rx(bp, rxr); ++ + hwrm_ring_free_send_msg(bp, ring, + RING_FREE_REQ_RING_TYPE_RX, + close_path ? cmpl_ring_id : +@@ -5169,10 +5169,10 @@ static void bnxt_hwrm_ring_free(struct b + struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i]; + struct bnxt_ring_struct *ring = &rxr->rx_agg_ring_struct; + u32 grp_idx = rxr->bnapi->index; +- u32 cmpl_ring_id; + +- cmpl_ring_id = bnxt_cp_ring_for_rx(bp, rxr); + if (ring->fw_ring_id != INVALID_HW_RING_ID) { ++ u32 cmpl_ring_id = bnxt_cp_ring_for_rx(bp, rxr); ++ + hwrm_ring_free_send_msg(bp, ring, type, + close_path ? cmpl_ring_id : + INVALID_HW_RING_ID); diff --git a/queue-5.0/bnxt_en-fix-statistics-context-reservation-logic.patch b/queue-5.0/bnxt_en-fix-statistics-context-reservation-logic.patch new file mode 100644 index 00000000000..247e169f288 --- /dev/null +++ b/queue-5.0/bnxt_en-fix-statistics-context-reservation-logic.patch @@ -0,0 +1,64 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Michael Chan +Date: Thu, 25 Apr 2019 22:31:54 -0400 +Subject: bnxt_en: Fix statistics context reservation logic. + +From: Michael Chan + +[ Upstream commit 3f93cd3f098e284c851acb89265ebe35b994a5c8 ] + +In an earlier commit that fixes the number of stats contexts to +reserve for the RDMA driver, we added a function parameter to pass in +the number of stats contexts to all the relevant functions. The passed +in parameter should have been used to set the enables field of the +firmware message. + +Fixes: 780baad44f0f ("bnxt_en: Reserve 1 stat_ctx for RDMA driver.") +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -5311,17 +5311,16 @@ __bnxt_hwrm_reserve_pf_rings(struct bnxt + req->num_tx_rings = cpu_to_le16(tx_rings); + if (BNXT_NEW_RM(bp)) { + enables |= rx_rings ? FUNC_CFG_REQ_ENABLES_NUM_RX_RINGS : 0; ++ enables |= stats ? FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0; + if (bp->flags & BNXT_FLAG_CHIP_P5) { + enables |= cp_rings ? FUNC_CFG_REQ_ENABLES_NUM_MSIX : 0; + enables |= tx_rings + ring_grps ? +- FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS | +- FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0; ++ FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS : 0; + enables |= rx_rings ? + FUNC_CFG_REQ_ENABLES_NUM_RSSCOS_CTXS : 0; + } else { + enables |= cp_rings ? +- FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS | +- FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0; ++ FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS : 0; + enables |= ring_grps ? + FUNC_CFG_REQ_ENABLES_NUM_HW_RING_GRPS | + FUNC_CFG_REQ_ENABLES_NUM_RSSCOS_CTXS : 0; +@@ -5361,14 +5360,13 @@ __bnxt_hwrm_reserve_vf_rings(struct bnxt + enables |= tx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_TX_RINGS : 0; + enables |= rx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_RX_RINGS | + FUNC_VF_CFG_REQ_ENABLES_NUM_RSSCOS_CTXS : 0; ++ enables |= stats ? FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0; + if (bp->flags & BNXT_FLAG_CHIP_P5) { + enables |= tx_rings + ring_grps ? +- FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS | +- FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0; ++ FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS : 0; + } else { + enables |= cp_rings ? +- FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS | +- FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0; ++ FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS : 0; + enables |= ring_grps ? + FUNC_VF_CFG_REQ_ENABLES_NUM_HW_RING_GRPS : 0; + } diff --git a/queue-5.0/bnxt_en-fix-uninitialized-variable-usage-in-bnxt_rx_pkt.patch b/queue-5.0/bnxt_en-fix-uninitialized-variable-usage-in-bnxt_rx_pkt.patch new file mode 100644 index 00000000000..ff7a00ed2d3 --- /dev/null +++ b/queue-5.0/bnxt_en-fix-uninitialized-variable-usage-in-bnxt_rx_pkt.patch @@ -0,0 +1,55 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Michael Chan +Date: Thu, 25 Apr 2019 22:31:55 -0400 +Subject: bnxt_en: Fix uninitialized variable usage in bnxt_rx_pkt(). + +From: Michael Chan + +[ Upstream commit 0b397b17a4120cb80f7bf89eb30587b3dd9b0d1d ] + +In bnxt_rx_pkt(), if the driver encounters BD errors, it will recycle +the buffers and jump to the end where the uninitailized variable "len" +is referenced. Fix it by adding a new jump label that will skip +the length update. This is the most correct fix since the length +may not be valid when we get this type of error. + +Fixes: 6a8788f25625 ("bnxt_en: add support for software dynamic interrupt moderation") +Reported-by: Nathan Chancellor +Cc: Nathan Chancellor +Signed-off-by: Michael Chan +Reviewed-by: Nathan Chancellor +Tested-by: Nathan Chancellor +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -1621,7 +1621,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, + netdev_warn(bp->dev, "RX buffer error %x\n", rx_err); + bnxt_sched_reset(bp, rxr); + } +- goto next_rx; ++ goto next_rx_no_len; + } + + len = le32_to_cpu(rxcmp->rx_cmp_len_flags_type) >> RX_CMP_LEN_SHIFT; +@@ -1702,12 +1702,13 @@ static int bnxt_rx_pkt(struct bnxt *bp, + rc = 1; + + next_rx: +- rxr->rx_prod = NEXT_RX(prod); +- rxr->rx_next_cons = NEXT_RX(cons); +- + cpr->rx_packets += 1; + cpr->rx_bytes += len; + ++next_rx_no_len: ++ rxr->rx_prod = NEXT_RX(prod); ++ rxr->rx_next_cons = NEXT_RX(cons); ++ + next_rx_no_prod_no_len: + *raw_cons = tmp_raw_cons; + diff --git a/queue-5.0/bnxt_en-free-short-fw-command-hwrm-memory-in-error-path-in-bnxt_init_one.patch b/queue-5.0/bnxt_en-free-short-fw-command-hwrm-memory-in-error-path-in-bnxt_init_one.patch new file mode 100644 index 00000000000..1836247c99d --- /dev/null +++ b/queue-5.0/bnxt_en-free-short-fw-command-hwrm-memory-in-error-path-in-bnxt_init_one.patch @@ -0,0 +1,31 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Vasundhara Volam +Date: Thu, 25 Apr 2019 22:31:51 -0400 +Subject: bnxt_en: Free short FW command HWRM memory in error path in bnxt_init_one() + +From: Vasundhara Volam + +[ Upstream commit f9099d611449836a51a65f40ea7dc9cb5f2f665e ] + +In the bnxt_init_one() error path, short FW command request memory +is not freed. This patch fixes it. + +Fixes: e605db801bde ("bnxt_en: Support for Short Firmware Message") +Signed-off-by: Vasundhara Volam +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -10632,6 +10632,7 @@ init_err_cleanup_tc: + bnxt_clear_int_mode(bp); + + init_err_pci_clean: ++ bnxt_free_hwrm_short_cmd_req(bp); + bnxt_free_hwrm_resources(bp); + bnxt_free_ctx_mem(bp); + kfree(bp->ctx); diff --git a/queue-5.0/bnxt_en-improve-multicast-address-setup-logic.patch b/queue-5.0/bnxt_en-improve-multicast-address-setup-logic.patch new file mode 100644 index 00000000000..cb9a2e38d7e --- /dev/null +++ b/queue-5.0/bnxt_en-improve-multicast-address-setup-logic.patch @@ -0,0 +1,43 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Michael Chan +Date: Thu, 25 Apr 2019 22:31:50 -0400 +Subject: bnxt_en: Improve multicast address setup logic. + +From: Michael Chan + +[ Upstream commit b4e30e8e7ea1d1e35ffd64ca46f7d9a7f227b4bf ] + +The driver builds a list of multicast addresses and sends it to the +firmware when the driver's ndo_set_rx_mode() is called. In rare +cases, the firmware can fail this call if internal resources to +add multicast addresses are exhausted. In that case, we should +try the call again by setting the ALL_MCAST flag which is more +guaranteed to succeed. + +Fixes: c0c050c58d84 ("bnxt_en: New Broadcom ethernet driver.") +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -8889,8 +8889,15 @@ static int bnxt_cfg_rx_mode(struct bnxt + + skip_uc: + rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0); ++ if (rc && vnic->mc_list_count) { ++ netdev_info(bp->dev, "Failed setting MC filters rc: %d, turning on ALL_MCAST mode\n", ++ rc); ++ vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST; ++ vnic->mc_list_count = 0; ++ rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0); ++ } + if (rc) +- netdev_err(bp->dev, "HWRM cfa l2 rx mask failure rc: %x\n", ++ netdev_err(bp->dev, "HWRM cfa l2 rx mask failure rc: %d\n", + rc); + + return rc; diff --git a/queue-5.0/bnxt_en-pass-correct-extended-tx-port-statistics-size-to-firmware.patch b/queue-5.0/bnxt_en-pass-correct-extended-tx-port-statistics-size-to-firmware.patch new file mode 100644 index 00000000000..397a50de96e --- /dev/null +++ b/queue-5.0/bnxt_en-pass-correct-extended-tx-port-statistics-size-to-firmware.patch @@ -0,0 +1,53 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Michael Chan +Date: Thu, 25 Apr 2019 22:31:53 -0400 +Subject: bnxt_en: Pass correct extended TX port statistics size to firmware. + +From: Michael Chan + +[ Upstream commit ad361adf0d08f1135f3845c6b3a36be7cc0bfda5 ] + +If driver determines that extended TX port statistics are not supported +or allocation of the data structure fails, make sure to pass 0 TX stats +size to firmware to disable it. The firmware returned TX stats size should +also be set to 0 for consistency. This will prevent +bnxt_get_ethtool_stats() from accessing the NULL TX stats pointer in +case there is mismatch between firmware and driver. + +Fixes: 36e53349b60b ("bnxt_en: Add additional extended port statistics.") +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -6745,6 +6745,7 @@ static int bnxt_hwrm_port_qstats_ext(str + struct hwrm_queue_pri2cos_qcfg_input req2 = {0}; + struct hwrm_port_qstats_ext_input req = {0}; + struct bnxt_pf_info *pf = &bp->pf; ++ u32 tx_stat_size; + int rc; + + if (!(bp->flags & BNXT_FLAG_PORT_STATS_EXT)) +@@ -6754,13 +6755,16 @@ static int bnxt_hwrm_port_qstats_ext(str + req.port_id = cpu_to_le16(pf->port_id); + req.rx_stat_size = cpu_to_le16(sizeof(struct rx_port_stats_ext)); + req.rx_stat_host_addr = cpu_to_le64(bp->hw_rx_port_stats_ext_map); +- req.tx_stat_size = cpu_to_le16(sizeof(struct tx_port_stats_ext)); ++ tx_stat_size = bp->hw_tx_port_stats_ext ? ++ sizeof(*bp->hw_tx_port_stats_ext) : 0; ++ req.tx_stat_size = cpu_to_le16(tx_stat_size); + req.tx_stat_host_addr = cpu_to_le64(bp->hw_tx_port_stats_ext_map); + mutex_lock(&bp->hwrm_cmd_lock); + rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + if (!rc) { + bp->fw_rx_stats_ext_size = le16_to_cpu(resp->rx_stat_size) / 8; +- bp->fw_tx_stats_ext_size = le16_to_cpu(resp->tx_stat_size) / 8; ++ bp->fw_tx_stats_ext_size = tx_stat_size ? ++ le16_to_cpu(resp->tx_stat_size) / 8 : 0; + } else { + bp->fw_rx_stats_ext_size = 0; + bp->fw_tx_stats_ext_size = 0; diff --git a/queue-5.0/ipv4-ip_do_fragment-preserve-skb_iif-during-fragmentation.patch b/queue-5.0/ipv4-ip_do_fragment-preserve-skb_iif-during-fragmentation.patch new file mode 100644 index 00000000000..0d88acba15c --- /dev/null +++ b/queue-5.0/ipv4-ip_do_fragment-preserve-skb_iif-during-fragmentation.patch @@ -0,0 +1,42 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Shmulik Ladkani +Date: Mon, 29 Apr 2019 16:39:30 +0300 +Subject: ipv4: ip_do_fragment: Preserve skb_iif during fragmentation + +From: Shmulik Ladkani + +[ Upstream commit d2f0c961148f65bc73eda72b9fa3a4e80973cb49 ] + +Previously, during fragmentation after forwarding, skb->skb_iif isn't +preserved, i.e. 'ip_copy_metadata' does not copy skb_iif from given +'from' skb. + +As a result, ip_do_fragment's creates fragments with zero skb_iif, +leading to inconsistent behavior. + +Assume for example an eBPF program attached at tc egress (post +forwarding) that examines __sk_buff->ingress_ifindex: + - the correct iif is observed if forwarding path does not involve + fragmentation/refragmentation + - a bogus iif is observed if forwarding path involves + fragmentation/refragmentatiom + +Fix, by preserving skb_iif during 'ip_copy_metadata'. + +Signed-off-by: Shmulik Ladkani +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_output.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -519,6 +519,7 @@ static void ip_copy_metadata(struct sk_b + to->pkt_type = from->pkt_type; + to->priority = from->priority; + to->protocol = from->protocol; ++ to->skb_iif = from->skb_iif; + skb_dst_drop(to); + skb_dst_copy(to, from); + to->dev = from->dev; diff --git a/queue-5.0/ipv6-a-few-fixes-on-dereferencing-rt-from.patch b/queue-5.0/ipv6-a-few-fixes-on-dereferencing-rt-from.patch new file mode 100644 index 00000000000..3d1b77ee62e --- /dev/null +++ b/queue-5.0/ipv6-a-few-fixes-on-dereferencing-rt-from.patch @@ -0,0 +1,108 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Martin KaFai Lau +Date: Tue, 30 Apr 2019 10:45:12 -0700 +Subject: ipv6: A few fixes on dereferencing rt->from + +From: Martin KaFai Lau + +[ Upstream commit 886b7a50100a50f1cbd08a6f8ec5884dfbe082dc ] + +It is a followup after the fix in +commit 9c69a1320515 ("route: Avoid crash from dereferencing NULL rt->from") + +rt6_do_redirect(): +1. NULL checking is needed on rt->from because a parallel + fib6_info delete could happen that sets rt->from to NULL. + (e.g. rt6_remove_exception() and fib6_drop_pcpu_from()). + +2. fib6_info_hold() is not enough. Same reason as (1). + Meaning, holding dst->__refcnt cannot ensure + rt->from is not NULL or rt->from->fib6_ref is not 0. + + Instead of using fib6_info_hold_safe() which ip6_rt_cache_alloc() + is already doing, this patch chooses to extend the rcu section + to keep "from" dereference-able after checking for NULL. + +inet6_rtm_getroute(): +1. NULL checking is also needed on rt->from for a similar reason. + Note that inet6_rtm_getroute() is using RTNL_FLAG_DOIT_UNLOCKED. + +Fixes: a68886a69180 ("net/ipv6: Make from in rt6_info rcu protected") +Signed-off-by: Martin KaFai Lau +Acked-by: Wei Wang +Reviewed-by: David Ahern +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/route.c | 38 ++++++++++++++++++-------------------- + 1 file changed, 18 insertions(+), 20 deletions(-) + +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -3403,11 +3403,8 @@ static void rt6_do_redirect(struct dst_e + + rcu_read_lock(); + from = rcu_dereference(rt->from); +- /* This fib6_info_hold() is safe here because we hold reference to rt +- * and rt already holds reference to fib6_info. +- */ +- fib6_info_hold(from); +- rcu_read_unlock(); ++ if (!from) ++ goto out; + + nrt = ip6_rt_cache_alloc(from, &msg->dest, NULL); + if (!nrt) +@@ -3419,10 +3416,7 @@ static void rt6_do_redirect(struct dst_e + + nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key; + +- /* No need to remove rt from the exception table if rt is +- * a cached route because rt6_insert_exception() will +- * takes care of it +- */ ++ /* rt6_insert_exception() will take care of duplicated exceptions */ + if (rt6_insert_exception(nrt, from)) { + dst_release_immediate(&nrt->dst); + goto out; +@@ -3435,7 +3429,7 @@ static void rt6_do_redirect(struct dst_e + call_netevent_notifiers(NETEVENT_REDIRECT, &netevent); + + out: +- fib6_info_release(from); ++ rcu_read_unlock(); + neigh_release(neigh); + } + +@@ -4957,16 +4951,20 @@ static int inet6_rtm_getroute(struct sk_ + + rcu_read_lock(); + from = rcu_dereference(rt->from); +- +- if (fibmatch) +- err = rt6_fill_node(net, skb, from, NULL, NULL, NULL, iif, +- RTM_NEWROUTE, NETLINK_CB(in_skb).portid, +- nlh->nlmsg_seq, 0); +- else +- err = rt6_fill_node(net, skb, from, dst, &fl6.daddr, +- &fl6.saddr, iif, RTM_NEWROUTE, +- NETLINK_CB(in_skb).portid, nlh->nlmsg_seq, +- 0); ++ if (from) { ++ if (fibmatch) ++ err = rt6_fill_node(net, skb, from, NULL, NULL, NULL, ++ iif, RTM_NEWROUTE, ++ NETLINK_CB(in_skb).portid, ++ nlh->nlmsg_seq, 0); ++ else ++ err = rt6_fill_node(net, skb, from, dst, &fl6.daddr, ++ &fl6.saddr, iif, RTM_NEWROUTE, ++ NETLINK_CB(in_skb).portid, ++ nlh->nlmsg_seq, 0); ++ } else { ++ err = -ENETUNREACH; ++ } + rcu_read_unlock(); + + if (err < 0) { diff --git a/queue-5.0/ipv6-fix-races-in-ip6_dst_destroy.patch b/queue-5.0/ipv6-fix-races-in-ip6_dst_destroy.patch new file mode 100644 index 00000000000..18acc9bc2d8 --- /dev/null +++ b/queue-5.0/ipv6-fix-races-in-ip6_dst_destroy.patch @@ -0,0 +1,140 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Eric Dumazet +Date: Sun, 28 Apr 2019 12:22:25 -0700 +Subject: ipv6: fix races in ip6_dst_destroy() + +From: Eric Dumazet + +[ Upstream commit 0e2338749192ce0e52e7174c5352f627632f478a ] + +We had many syzbot reports that seem to be caused by use-after-free +of struct fib6_info. + +ip6_dst_destroy(), fib6_drop_pcpu_from() and rt6_remove_exception() +are writers vs rt->from, and use non consistent synchronization among +themselves. + +Switching to xchg() will solve the issues with no possible +lockdep issues. + +BUG: KASAN: user-memory-access in atomic_dec_and_test include/asm-generic/atomic-instrumented.h:747 [inline] +BUG: KASAN: user-memory-access in fib6_info_release include/net/ip6_fib.h:294 [inline] +BUG: KASAN: user-memory-access in fib6_info_release include/net/ip6_fib.h:292 [inline] +BUG: KASAN: user-memory-access in fib6_drop_pcpu_from net/ipv6/ip6_fib.c:927 [inline] +BUG: KASAN: user-memory-access in fib6_purge_rt+0x4f6/0x670 net/ipv6/ip6_fib.c:960 +Write of size 4 at addr 0000000000ffffb4 by task syz-executor.1/7649 + +CPU: 0 PID: 7649 Comm: syz-executor.1 Not tainted 5.1.0-rc6+ #183 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x172/0x1f0 lib/dump_stack.c:113 + kasan_report.cold+0x5/0x40 mm/kasan/report.c:321 + check_memory_region_inline mm/kasan/generic.c:185 [inline] + check_memory_region+0x123/0x190 mm/kasan/generic.c:191 + kasan_check_write+0x14/0x20 mm/kasan/common.c:108 + atomic_dec_and_test include/asm-generic/atomic-instrumented.h:747 [inline] + fib6_info_release include/net/ip6_fib.h:294 [inline] + fib6_info_release include/net/ip6_fib.h:292 [inline] + fib6_drop_pcpu_from net/ipv6/ip6_fib.c:927 [inline] + fib6_purge_rt+0x4f6/0x670 net/ipv6/ip6_fib.c:960 + fib6_del_route net/ipv6/ip6_fib.c:1813 [inline] + fib6_del+0xac2/0x10a0 net/ipv6/ip6_fib.c:1844 + fib6_clean_node+0x3a8/0x590 net/ipv6/ip6_fib.c:2006 + fib6_walk_continue+0x495/0x900 net/ipv6/ip6_fib.c:1928 + fib6_walk+0x9d/0x100 net/ipv6/ip6_fib.c:1976 + fib6_clean_tree+0xe0/0x120 net/ipv6/ip6_fib.c:2055 + __fib6_clean_all+0x118/0x2a0 net/ipv6/ip6_fib.c:2071 + fib6_clean_all+0x2b/0x40 net/ipv6/ip6_fib.c:2082 + rt6_sync_down_dev+0x134/0x150 net/ipv6/route.c:4057 + rt6_disable_ip+0x27/0x5f0 net/ipv6/route.c:4062 + addrconf_ifdown+0xa2/0x1220 net/ipv6/addrconf.c:3705 + addrconf_notify+0x19a/0x2260 net/ipv6/addrconf.c:3630 + notifier_call_chain+0xc7/0x240 kernel/notifier.c:93 + __raw_notifier_call_chain kernel/notifier.c:394 [inline] + raw_notifier_call_chain+0x2e/0x40 kernel/notifier.c:401 + call_netdevice_notifiers_info+0x3f/0x90 net/core/dev.c:1753 + call_netdevice_notifiers_extack net/core/dev.c:1765 [inline] + call_netdevice_notifiers net/core/dev.c:1779 [inline] + dev_close_many+0x33f/0x6f0 net/core/dev.c:1522 + rollback_registered_many+0x43b/0xfd0 net/core/dev.c:8177 + rollback_registered+0x109/0x1d0 net/core/dev.c:8242 + unregister_netdevice_queue net/core/dev.c:9289 [inline] + unregister_netdevice_queue+0x1ee/0x2c0 net/core/dev.c:9282 + unregister_netdevice include/linux/netdevice.h:2658 [inline] + __tun_detach+0xd5b/0x1000 drivers/net/tun.c:727 + tun_detach drivers/net/tun.c:744 [inline] + tun_chr_close+0xe0/0x180 drivers/net/tun.c:3443 + __fput+0x2e5/0x8d0 fs/file_table.c:278 + ____fput+0x16/0x20 fs/file_table.c:309 + task_work_run+0x14a/0x1c0 kernel/task_work.c:113 + exit_task_work include/linux/task_work.h:22 [inline] + do_exit+0x90a/0x2fa0 kernel/exit.c:876 + do_group_exit+0x135/0x370 kernel/exit.c:980 + __do_sys_exit_group kernel/exit.c:991 [inline] + __se_sys_exit_group kernel/exit.c:989 [inline] + __x64_sys_exit_group+0x44/0x50 kernel/exit.c:989 + do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290 + entry_SYSCALL_64_after_hwframe+0x49/0xbe +RIP: 0033:0x458da9 +Code: ad b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 7b b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00 +RSP: 002b:00007ffeafc2a6a8 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7 +RAX: ffffffffffffffda RBX: 000000000000001c RCX: 0000000000458da9 +RDX: 0000000000412a80 RSI: 0000000000a54ef0 RDI: 0000000000000043 +RBP: 00000000004be552 R08: 000000000000000c R09: 000000000004c0d1 +R10: 0000000002341940 R11: 0000000000000246 R12: 00000000ffffffff +R13: 00007ffeafc2a7f0 R14: 000000000004c065 R15: 00007ffeafc2a800 + +Fixes: a68886a69180 ("net/ipv6: Make from in rt6_info rcu protected") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Cc: David Ahern +Reviewed-by: David Ahern +Acked-by: Martin KaFai Lau +Acked-by: Wei Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_fib.c | 4 +--- + net/ipv6/route.c | 9 ++------- + 2 files changed, 3 insertions(+), 10 deletions(-) + +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -921,9 +921,7 @@ static void fib6_drop_pcpu_from(struct f + if (pcpu_rt) { + struct fib6_info *from; + +- from = rcu_dereference_protected(pcpu_rt->from, +- lockdep_is_held(&table->tb6_lock)); +- rcu_assign_pointer(pcpu_rt->from, NULL); ++ from = xchg((__force struct fib6_info **)&pcpu_rt->from, NULL); + fib6_info_release(from); + } + } +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -379,11 +379,8 @@ static void ip6_dst_destroy(struct dst_e + in6_dev_put(idev); + } + +- rcu_read_lock(); +- from = rcu_dereference(rt->from); +- rcu_assign_pointer(rt->from, NULL); ++ from = xchg((__force struct fib6_info **)&rt->from, NULL); + fib6_info_release(from); +- rcu_read_unlock(); + } + + static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, +@@ -1288,9 +1285,7 @@ static void rt6_remove_exception(struct + /* purge completely the exception to allow releasing the held resources: + * some [sk] cache may keep the dst around for unlimited time + */ +- from = rcu_dereference_protected(rt6_ex->rt6i->from, +- lockdep_is_held(&rt6_exception_lock)); +- rcu_assign_pointer(rt6_ex->rt6i->from, NULL); ++ from = xchg((__force struct fib6_info **)&rt6_ex->rt6i->from, NULL); + fib6_info_release(from); + dst_dev_put(&rt6_ex->rt6i->dst); + diff --git a/queue-5.0/ipv6-flowlabel-wait-rcu-grace-period-before-put_pid.patch b/queue-5.0/ipv6-flowlabel-wait-rcu-grace-period-before-put_pid.patch new file mode 100644 index 00000000000..554f67297fc --- /dev/null +++ b/queue-5.0/ipv6-flowlabel-wait-rcu-grace-period-before-put_pid.patch @@ -0,0 +1,151 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Eric Dumazet +Date: Sat, 27 Apr 2019 16:49:06 -0700 +Subject: ipv6/flowlabel: wait rcu grace period before put_pid() + +From: Eric Dumazet + +[ Upstream commit 6c0afef5fb0c27758f4d52b2210c61b6bd8b4470 ] + +syzbot was able to catch a use-after-free read in pid_nr_ns() [1] + +ip6fl_seq_show() seems to use RCU protection, dereferencing fl->owner.pid +but fl_free() releases fl->owner.pid before rcu grace period is started. + +[1] + +BUG: KASAN: use-after-free in pid_nr_ns+0x128/0x140 kernel/pid.c:407 +Read of size 4 at addr ffff888094012a04 by task syz-executor.0/18087 + +CPU: 0 PID: 18087 Comm: syz-executor.0 Not tainted 5.1.0-rc6+ #89 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x172/0x1f0 lib/dump_stack.c:113 + print_address_description.cold+0x7c/0x20d mm/kasan/report.c:187 + kasan_report.cold+0x1b/0x40 mm/kasan/report.c:317 + __asan_report_load4_noabort+0x14/0x20 mm/kasan/generic_report.c:131 + pid_nr_ns+0x128/0x140 kernel/pid.c:407 + ip6fl_seq_show+0x2f8/0x4f0 net/ipv6/ip6_flowlabel.c:794 + seq_read+0xad3/0x1130 fs/seq_file.c:268 + proc_reg_read+0x1fe/0x2c0 fs/proc/inode.c:227 + do_loop_readv_writev fs/read_write.c:701 [inline] + do_loop_readv_writev fs/read_write.c:688 [inline] + do_iter_read+0x4a9/0x660 fs/read_write.c:922 + vfs_readv+0xf0/0x160 fs/read_write.c:984 + kernel_readv fs/splice.c:358 [inline] + default_file_splice_read+0x475/0x890 fs/splice.c:413 + do_splice_to+0x12a/0x190 fs/splice.c:876 + splice_direct_to_actor+0x2d2/0x970 fs/splice.c:953 + do_splice_direct+0x1da/0x2a0 fs/splice.c:1062 + do_sendfile+0x597/0xd00 fs/read_write.c:1443 + __do_sys_sendfile64 fs/read_write.c:1498 [inline] + __se_sys_sendfile64 fs/read_write.c:1490 [inline] + __x64_sys_sendfile64+0x15a/0x220 fs/read_write.c:1490 + do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290 + entry_SYSCALL_64_after_hwframe+0x49/0xbe +RIP: 0033:0x458da9 +Code: ad b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 7b b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00 +RSP: 002b:00007f300d24bc78 EFLAGS: 00000246 ORIG_RAX: 0000000000000028 +RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 0000000000458da9 +RDX: 00000000200000c0 RSI: 0000000000000008 RDI: 0000000000000007 +RBP: 000000000073bf00 R08: 0000000000000000 R09: 0000000000000000 +R10: 000000000000005a R11: 0000000000000246 R12: 00007f300d24c6d4 +R13: 00000000004c5fa3 R14: 00000000004da748 R15: 00000000ffffffff + +Allocated by task 17543: + save_stack+0x45/0xd0 mm/kasan/common.c:75 + set_track mm/kasan/common.c:87 [inline] + __kasan_kmalloc mm/kasan/common.c:497 [inline] + __kasan_kmalloc.constprop.0+0xcf/0xe0 mm/kasan/common.c:470 + kasan_slab_alloc+0xf/0x20 mm/kasan/common.c:505 + slab_post_alloc_hook mm/slab.h:437 [inline] + slab_alloc mm/slab.c:3393 [inline] + kmem_cache_alloc+0x11a/0x6f0 mm/slab.c:3555 + alloc_pid+0x55/0x8f0 kernel/pid.c:168 + copy_process.part.0+0x3b08/0x7980 kernel/fork.c:1932 + copy_process kernel/fork.c:1709 [inline] + _do_fork+0x257/0xfd0 kernel/fork.c:2226 + __do_sys_clone kernel/fork.c:2333 [inline] + __se_sys_clone kernel/fork.c:2327 [inline] + __x64_sys_clone+0xbf/0x150 kernel/fork.c:2327 + do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +Freed by task 7789: + save_stack+0x45/0xd0 mm/kasan/common.c:75 + set_track mm/kasan/common.c:87 [inline] + __kasan_slab_free+0x102/0x150 mm/kasan/common.c:459 + kasan_slab_free+0xe/0x10 mm/kasan/common.c:467 + __cache_free mm/slab.c:3499 [inline] + kmem_cache_free+0x86/0x260 mm/slab.c:3765 + put_pid.part.0+0x111/0x150 kernel/pid.c:111 + put_pid+0x20/0x30 kernel/pid.c:105 + fl_free+0xbe/0xe0 net/ipv6/ip6_flowlabel.c:102 + ip6_fl_gc+0x295/0x3e0 net/ipv6/ip6_flowlabel.c:152 + call_timer_fn+0x190/0x720 kernel/time/timer.c:1325 + expire_timers kernel/time/timer.c:1362 [inline] + __run_timers kernel/time/timer.c:1681 [inline] + __run_timers kernel/time/timer.c:1649 [inline] + run_timer_softirq+0x652/0x1700 kernel/time/timer.c:1694 + __do_softirq+0x266/0x95a kernel/softirq.c:293 + +The buggy address belongs to the object at ffff888094012a00 + which belongs to the cache pid_2 of size 88 +The buggy address is located 4 bytes inside of + 88-byte region [ffff888094012a00, ffff888094012a58) +The buggy address belongs to the page: +page:ffffea0002500480 count:1 mapcount:0 mapping:ffff88809a483080 index:0xffff888094012980 +flags: 0x1fffc0000000200(slab) +raw: 01fffc0000000200 ffffea00018a3508 ffffea0002524a88 ffff88809a483080 +raw: ffff888094012980 ffff888094012000 000000010000001b 0000000000000000 +page dumped because: kasan: bad access detected + +Memory state around the buggy address: + ffff888094012900: fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc + ffff888094012980: fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc +>ffff888094012a00: fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc + ^ + ffff888094012a80: fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc + ffff888094012b00: fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc + +Fixes: 4f82f45730c6 ("net ip6 flowlabel: Make owner a union of struct pid * and kuid_t") +Signed-off-by: Eric Dumazet +Cc: Eric W. Biederman +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_flowlabel.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +--- a/net/ipv6/ip6_flowlabel.c ++++ b/net/ipv6/ip6_flowlabel.c +@@ -94,15 +94,21 @@ static struct ip6_flowlabel *fl_lookup(s + return fl; + } + ++static void fl_free_rcu(struct rcu_head *head) ++{ ++ struct ip6_flowlabel *fl = container_of(head, struct ip6_flowlabel, rcu); ++ ++ if (fl->share == IPV6_FL_S_PROCESS) ++ put_pid(fl->owner.pid); ++ kfree(fl->opt); ++ kfree(fl); ++} ++ + + static void fl_free(struct ip6_flowlabel *fl) + { +- if (fl) { +- if (fl->share == IPV6_FL_S_PROCESS) +- put_pid(fl->owner.pid); +- kfree(fl->opt); +- kfree_rcu(fl, rcu); +- } ++ if (fl) ++ call_rcu(&fl->rcu, fl_free_rcu); + } + + static void fl_release(struct ip6_flowlabel *fl) diff --git a/queue-5.0/ipv6-invert-flowlabel-sharing-check-in-process-and-user-mode.patch b/queue-5.0/ipv6-invert-flowlabel-sharing-check-in-process-and-user-mode.patch new file mode 100644 index 00000000000..2de69885602 --- /dev/null +++ b/queue-5.0/ipv6-invert-flowlabel-sharing-check-in-process-and-user-mode.patch @@ -0,0 +1,37 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Willem de Bruijn +Date: Thu, 25 Apr 2019 12:06:54 -0400 +Subject: ipv6: invert flowlabel sharing check in process and user mode + +From: Willem de Bruijn + +[ Upstream commit 95c169251bf734aa555a1e8043e4d88ec97a04ec ] + +A request for a flowlabel fails in process or user exclusive mode must +fail if the caller pid or uid does not match. Invert the test. + +Previously, the test was unsafe wrt PID recycling, but indeed tested +for inequality: fl1->owner != fl->owner + +Fixes: 4f82f45730c68 ("net ip6 flowlabel: Make owner a union of struct pid* and kuid_t") +Signed-off-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_flowlabel.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv6/ip6_flowlabel.c ++++ b/net/ipv6/ip6_flowlabel.c +@@ -639,9 +639,9 @@ recheck: + if (fl1->share == IPV6_FL_S_EXCL || + fl1->share != fl->share || + ((fl1->share == IPV6_FL_S_PROCESS) && +- (fl1->owner.pid == fl->owner.pid)) || ++ (fl1->owner.pid != fl->owner.pid)) || + ((fl1->share == IPV6_FL_S_USER) && +- uid_eq(fl1->owner.uid, fl->owner.uid))) ++ !uid_eq(fl1->owner.uid, fl->owner.uid))) + goto release; + + err = -ENOMEM; diff --git a/queue-5.0/l2ip-fix-possible-use-after-free.patch b/queue-5.0/l2ip-fix-possible-use-after-free.patch new file mode 100644 index 00000000000..c8f1ec8e420 --- /dev/null +++ b/queue-5.0/l2ip-fix-possible-use-after-free.patch @@ -0,0 +1,82 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Eric Dumazet +Date: Tue, 30 Apr 2019 06:27:58 -0700 +Subject: l2ip: fix possible use-after-free + +From: Eric Dumazet + +[ Upstream commit a622b40035d16196bf19b2b33b854862595245fc ] + +Before taking a refcount on a rcu protected structure, +we need to make sure the refcount is not zero. + +syzbot reported : + +refcount_t: increment on 0; use-after-free. +WARNING: CPU: 1 PID: 23533 at lib/refcount.c:156 refcount_inc_checked lib/refcount.c:156 [inline] +WARNING: CPU: 1 PID: 23533 at lib/refcount.c:156 refcount_inc_checked+0x61/0x70 lib/refcount.c:154 +Kernel panic - not syncing: panic_on_warn set ... +CPU: 1 PID: 23533 Comm: syz-executor.2 Not tainted 5.1.0-rc7+ #93 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x172/0x1f0 lib/dump_stack.c:113 + panic+0x2cb/0x65c kernel/panic.c:214 + __warn.cold+0x20/0x45 kernel/panic.c:571 + report_bug+0x263/0x2b0 lib/bug.c:186 + fixup_bug arch/x86/kernel/traps.c:179 [inline] + fixup_bug arch/x86/kernel/traps.c:174 [inline] + do_error_trap+0x11b/0x200 arch/x86/kernel/traps.c:272 + do_invalid_op+0x37/0x50 arch/x86/kernel/traps.c:291 + invalid_op+0x14/0x20 arch/x86/entry/entry_64.S:973 +RIP: 0010:refcount_inc_checked lib/refcount.c:156 [inline] +RIP: 0010:refcount_inc_checked+0x61/0x70 lib/refcount.c:154 +Code: 1d 98 2b 2a 06 31 ff 89 de e8 db 2c 40 fe 84 db 75 dd e8 92 2b 40 fe 48 c7 c7 20 7a a1 87 c6 05 78 2b 2a 06 01 e8 7d d9 12 fe <0f> 0b eb c1 90 90 90 90 90 90 90 90 90 90 90 55 48 89 e5 41 57 41 +RSP: 0018:ffff888069f0fba8 EFLAGS: 00010286 +RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 +RDX: 000000000000f353 RSI: ffffffff815afcb6 RDI: ffffed100d3e1f67 +RBP: ffff888069f0fbb8 R08: ffff88809b1845c0 R09: ffffed1015d23ef1 +R10: ffffed1015d23ef0 R11: ffff8880ae91f787 R12: ffff8880a8f26968 +R13: 0000000000000004 R14: dffffc0000000000 R15: ffff8880a49a6440 + l2tp_tunnel_inc_refcount net/l2tp/l2tp_core.h:240 [inline] + l2tp_tunnel_get+0x250/0x580 net/l2tp/l2tp_core.c:173 + pppol2tp_connect+0xc00/0x1c70 net/l2tp/l2tp_ppp.c:702 + __sys_connect+0x266/0x330 net/socket.c:1808 + __do_sys_connect net/socket.c:1819 [inline] + __se_sys_connect net/socket.c:1816 [inline] + __x64_sys_connect+0x73/0xb0 net/socket.c:1816 + +Fixes: 54652eb12c1b ("l2tp: hold tunnel while looking up sessions in l2tp_netlink") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Cc: Guillaume Nault +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_core.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -169,8 +169,8 @@ struct l2tp_tunnel *l2tp_tunnel_get(cons + + rcu_read_lock_bh(); + list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) { +- if (tunnel->tunnel_id == tunnel_id) { +- l2tp_tunnel_inc_refcount(tunnel); ++ if (tunnel->tunnel_id == tunnel_id && ++ refcount_inc_not_zero(&tunnel->ref_count)) { + rcu_read_unlock_bh(); + + return tunnel; +@@ -190,8 +190,8 @@ struct l2tp_tunnel *l2tp_tunnel_get_nth( + + rcu_read_lock_bh(); + list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) { +- if (++count > nth) { +- l2tp_tunnel_inc_refcount(tunnel); ++ if (++count > nth && ++ refcount_inc_not_zero(&tunnel->ref_count)) { + rcu_read_unlock_bh(); + return tunnel; + } diff --git a/queue-5.0/l2tp-use-rcu_dereference_sk_user_data-in-l2tp_udp_encap_recv.patch b/queue-5.0/l2tp-use-rcu_dereference_sk_user_data-in-l2tp_udp_encap_recv.patch new file mode 100644 index 00000000000..dae2a202313 --- /dev/null +++ b/queue-5.0/l2tp-use-rcu_dereference_sk_user_data-in-l2tp_udp_encap_recv.patch @@ -0,0 +1,33 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Eric Dumazet +Date: Tue, 23 Apr 2019 09:43:26 -0700 +Subject: l2tp: use rcu_dereference_sk_user_data() in l2tp_udp_encap_recv() + +From: Eric Dumazet + +[ Upstream commit c1c477217882c610a2ba0268f5faf36c9c092528 ] + +Canonical way to fetch sk_user_data from an encap_rcv() handler called +from UDP stack in rcu protected section is to use rcu_dereference_sk_user_data(), +otherwise compiler might read it multiple times. + +Fixes: d00fa9adc528 ("il2tp: fix races with tunnel socket close") +Signed-off-by: Eric Dumazet +Cc: James Chapman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -909,7 +909,7 @@ int l2tp_udp_encap_recv(struct sock *sk, + { + struct l2tp_tunnel *tunnel; + +- tunnel = l2tp_tunnel(sk); ++ tunnel = rcu_dereference_sk_user_data(sk); + if (tunnel == NULL) + goto pass_up; + diff --git a/queue-5.0/net-dsa-bcm_sf2-fix-buffer-overflow-doing-set_rxnfc.patch b/queue-5.0/net-dsa-bcm_sf2-fix-buffer-overflow-doing-set_rxnfc.patch new file mode 100644 index 00000000000..ed9cffd7da1 --- /dev/null +++ b/queue-5.0/net-dsa-bcm_sf2-fix-buffer-overflow-doing-set_rxnfc.patch @@ -0,0 +1,43 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Dan Carpenter +Date: Tue, 30 Apr 2019 13:44:19 +0300 +Subject: net: dsa: bcm_sf2: fix buffer overflow doing set_rxnfc + +From: Dan Carpenter + +[ Upstream commit f949a12fd697479f68d99dc65e9bbab68ee49043 ] + +The "fs->location" is a u32 that comes from the user in ethtool_set_rxnfc(). +We can't pass unclamped values to test_bit() or it results in an out of +bounds access beyond the end of the bitmap. + +Fixes: 7318166cacad ("net: dsa: bcm_sf2: Add support for ethtool::rxnfc") +Signed-off-by: Dan Carpenter +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/dsa/bcm_sf2_cfp.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/dsa/bcm_sf2_cfp.c ++++ b/drivers/net/dsa/bcm_sf2_cfp.c +@@ -854,6 +854,9 @@ static int bcm_sf2_cfp_rule_set(struct d + fs->m_ext.data[1])) + return -EINVAL; + ++ if (fs->location != RX_CLS_LOC_ANY && fs->location >= CFP_NUM_RULES) ++ return -EINVAL; ++ + if (fs->location != RX_CLS_LOC_ANY && + test_bit(fs->location, priv->cfp.used)) + return -EBUSY; +@@ -942,6 +945,9 @@ static int bcm_sf2_cfp_rule_del(struct b + struct cfp_rule *rule; + int ret; + ++ if (loc >= CFP_NUM_RULES) ++ return -EINVAL; ++ + /* Refuse deleting unused rules, and those that are not unique since + * that could leave IPv6 rules with one of the chained rule in the + * table. diff --git a/queue-5.0/net-phy-marvell-fix-buffer-overrun-with-stats-counters.patch b/queue-5.0/net-phy-marvell-fix-buffer-overrun-with-stats-counters.patch new file mode 100644 index 00000000000..2825bfded89 --- /dev/null +++ b/queue-5.0/net-phy-marvell-fix-buffer-overrun-with-stats-counters.patch @@ -0,0 +1,51 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Andrew Lunn +Date: Thu, 25 Apr 2019 00:33:00 +0200 +Subject: net: phy: marvell: Fix buffer overrun with stats counters + +From: Andrew Lunn + +[ Upstream commit fdfdf86720a34527f777cbe0d8599bf0528fa146 ] + +marvell_get_sset_count() returns how many statistics counters there +are. If the PHY supports fibre, there are 3, otherwise two. + +marvell_get_strings() does not make this distinction, and always +returns 3 strings. This then often results in writing past the end +of the buffer for the strings. + +Fixes: 2170fef78a40 ("Marvell phy: add field to get errors from fiber link.") +Signed-off-by: Andrew Lunn +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/marvell.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/phy/marvell.c ++++ b/drivers/net/phy/marvell.c +@@ -1494,9 +1494,10 @@ static int marvell_get_sset_count(struct + + static void marvell_get_strings(struct phy_device *phydev, u8 *data) + { ++ int count = marvell_get_sset_count(phydev); + int i; + +- for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) { ++ for (i = 0; i < count; i++) { + strlcpy(data + i * ETH_GSTRING_LEN, + marvell_hw_stats[i].string, ETH_GSTRING_LEN); + } +@@ -1524,9 +1525,10 @@ static u64 marvell_get_stat(struct phy_d + static void marvell_get_stats(struct phy_device *phydev, + struct ethtool_stats *stats, u64 *data) + { ++ int count = marvell_get_sset_count(phydev); + int i; + +- for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) ++ for (i = 0; i < count; i++) + data[i] = marvell_get_stat(phydev, i); + } + diff --git a/queue-5.0/net-tls-avoid-null-pointer-deref-on-nskb-sk-in-fallback.patch b/queue-5.0/net-tls-avoid-null-pointer-deref-on-nskb-sk-in-fallback.patch new file mode 100644 index 00000000000..5fed5ac464e --- /dev/null +++ b/queue-5.0/net-tls-avoid-null-pointer-deref-on-nskb-sk-in-fallback.patch @@ -0,0 +1,39 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Jakub Kicinski +Date: Mon, 29 Apr 2019 12:19:12 -0700 +Subject: net/tls: avoid NULL pointer deref on nskb->sk in fallback + +From: Jakub Kicinski + +[ Upstream commit 2dcb003314032c6efb13a065ffae60d164b2dd35 ] + +update_chksum() accesses nskb->sk before it has been set +by complete_skb(), move the init up. + +Fixes: e8f69799810c ("net/tls: Add generic NIC offload infrastructure") +Signed-off-by: Jakub Kicinski +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tls/tls_device_fallback.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/tls/tls_device_fallback.c ++++ b/net/tls/tls_device_fallback.c +@@ -200,13 +200,14 @@ static void complete_skb(struct sk_buff + + skb_put(nskb, skb->len); + memcpy(nskb->data, skb->data, headln); +- update_chksum(nskb, headln); + + nskb->destructor = skb->destructor; + nskb->sk = sk; + skb->destructor = NULL; + skb->sk = NULL; + ++ update_chksum(nskb, headln); ++ + delta = nskb->truesize - skb->truesize; + if (likely(delta < 0)) + WARN_ON_ONCE(refcount_sub_and_test(-delta, &sk->sk_wmem_alloc)); diff --git a/queue-5.0/net-tls-don-t-copy-negative-amounts-of-data-in-reencrypt.patch b/queue-5.0/net-tls-don-t-copy-negative-amounts-of-data-in-reencrypt.patch new file mode 100644 index 00000000000..b4110e5ed33 --- /dev/null +++ b/queue-5.0/net-tls-don-t-copy-negative-amounts-of-data-in-reencrypt.patch @@ -0,0 +1,48 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Jakub Kicinski +Date: Thu, 25 Apr 2019 17:35:09 -0700 +Subject: net/tls: don't copy negative amounts of data in reencrypt + +From: Jakub Kicinski + +[ Upstream commit 97e1caa517e22d62a283b876fb8aa5f4672c83dd ] + +There is no guarantee the record starts before the skb frags. +If we don't check for this condition copy amount will get +negative, leading to reads and writes to random memory locations. +Familiar hilarity ensues. + +Fixes: 4799ac81e52a ("tls: Add rx inline crypto offload") +Signed-off-by: Jakub Kicinski +Reviewed-by: John Hurley +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tls/tls_device.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +--- a/net/tls/tls_device.c ++++ b/net/tls/tls_device.c +@@ -610,14 +610,16 @@ static int tls_device_reencrypt(struct s + else + err = 0; + +- copy = min_t(int, skb_pagelen(skb) - offset, +- rxm->full_len - TLS_CIPHER_AES_GCM_128_TAG_SIZE); ++ if (skb_pagelen(skb) > offset) { ++ copy = min_t(int, skb_pagelen(skb) - offset, ++ rxm->full_len - TLS_CIPHER_AES_GCM_128_TAG_SIZE); + +- if (skb->decrypted) +- skb_store_bits(skb, offset, buf, copy); ++ if (skb->decrypted) ++ skb_store_bits(skb, offset, buf, copy); + +- offset += copy; +- buf += copy; ++ offset += copy; ++ buf += copy; ++ } + + skb_walk_frags(skb, skb_iter) { + copy = min_t(int, skb_iter->len, diff --git a/queue-5.0/net-tls-fix-copy-to-fragments-in-reencrypt.patch b/queue-5.0/net-tls-fix-copy-to-fragments-in-reencrypt.patch new file mode 100644 index 00000000000..9dec1daeea1 --- /dev/null +++ b/queue-5.0/net-tls-fix-copy-to-fragments-in-reencrypt.patch @@ -0,0 +1,85 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Jakub Kicinski +Date: Thu, 25 Apr 2019 17:35:10 -0700 +Subject: net/tls: fix copy to fragments in reencrypt + +From: Jakub Kicinski + +[ Upstream commit eb3d38d5adb520435d4e4af32529ccb13ccc9935 ] + +Fragments may contain data from other records so we have to account +for that when we calculate the destination and max length of copy we +can perform. Note that 'offset' is the offset within the message, +so it can't be passed as offset within the frag.. + +Here skb_store_bits() would have realised the call is wrong and +simply not copy data. + +Fixes: 4799ac81e52a ("tls: Add rx inline crypto offload") +Signed-off-by: Jakub Kicinski +Reviewed-by: John Hurley +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tls/tls_device.c | 29 ++++++++++++++++++++++------- + 1 file changed, 22 insertions(+), 7 deletions(-) + +--- a/net/tls/tls_device.c ++++ b/net/tls/tls_device.c +@@ -579,7 +579,7 @@ void handle_device_resync(struct sock *s + static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb) + { + struct strp_msg *rxm = strp_msg(skb); +- int err = 0, offset = rxm->offset, copy, nsg; ++ int err = 0, offset = rxm->offset, copy, nsg, data_len, pos; + struct sk_buff *skb_iter, *unused; + struct scatterlist sg[1]; + char *orig_buf, *buf; +@@ -610,9 +610,10 @@ static int tls_device_reencrypt(struct s + else + err = 0; + ++ data_len = rxm->full_len - TLS_CIPHER_AES_GCM_128_TAG_SIZE; ++ + if (skb_pagelen(skb) > offset) { +- copy = min_t(int, skb_pagelen(skb) - offset, +- rxm->full_len - TLS_CIPHER_AES_GCM_128_TAG_SIZE); ++ copy = min_t(int, skb_pagelen(skb) - offset, data_len); + + if (skb->decrypted) + skb_store_bits(skb, offset, buf, copy); +@@ -621,16 +622,30 @@ static int tls_device_reencrypt(struct s + buf += copy; + } + ++ pos = skb_pagelen(skb); + skb_walk_frags(skb, skb_iter) { +- copy = min_t(int, skb_iter->len, +- rxm->full_len - offset + rxm->offset - +- TLS_CIPHER_AES_GCM_128_TAG_SIZE); ++ int frag_pos; ++ ++ /* Practically all frags must belong to msg if reencrypt ++ * is needed with current strparser and coalescing logic, ++ * but strparser may "get optimized", so let's be safe. ++ */ ++ if (pos + skb_iter->len <= offset) ++ goto done_with_frag; ++ if (pos >= data_len + rxm->offset) ++ break; ++ ++ frag_pos = offset - pos; ++ copy = min_t(int, skb_iter->len - frag_pos, ++ data_len + rxm->offset - offset); + + if (skb_iter->decrypted) +- skb_store_bits(skb_iter, offset, buf, copy); ++ skb_store_bits(skb_iter, frag_pos, buf, copy); + + offset += copy; + buf += copy; ++done_with_frag: ++ pos += skb_iter->len; + } + + free_buf: diff --git a/queue-5.0/packet-in-recvmsg-msg_name-return-at-least-sizeof-sockaddr_ll.patch b/queue-5.0/packet-in-recvmsg-msg_name-return-at-least-sizeof-sockaddr_ll.patch new file mode 100644 index 00000000000..d47f7df63c3 --- /dev/null +++ b/queue-5.0/packet-in-recvmsg-msg_name-return-at-least-sizeof-sockaddr_ll.patch @@ -0,0 +1,64 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Willem de Bruijn +Date: Mon, 29 Apr 2019 11:46:55 -0400 +Subject: packet: in recvmsg msg_name return at least sizeof sockaddr_ll + +From: Willem de Bruijn + +[ Upstream commit b2cf86e1563e33a14a1c69b3e508d15dc12f804c ] + +Packet send checks that msg_name is at least sizeof sockaddr_ll. +Packet recv must return at least this length, so that its output +can be passed unmodified to packet send. + +This ceased to be true since adding support for lladdr longer than +sll_addr. Since, the return value uses true address length. + +Always return at least sizeof sockaddr_ll, even if address length +is shorter. Zero the padding bytes. + +Change v1->v2: do not overwrite zeroed padding again. use copy_len. + +Fixes: 0fb375fb9b93 ("[AF_PACKET]: Allow for > 8 byte hardware addresses.") +Suggested-by: David Laight +Signed-off-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/packet/af_packet.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -3349,20 +3349,29 @@ static int packet_recvmsg(struct socket + sock_recv_ts_and_drops(msg, sk, skb); + + if (msg->msg_name) { ++ int copy_len; ++ + /* If the address length field is there to be filled + * in, we fill it in now. + */ + if (sock->type == SOCK_PACKET) { + __sockaddr_check_size(sizeof(struct sockaddr_pkt)); + msg->msg_namelen = sizeof(struct sockaddr_pkt); ++ copy_len = msg->msg_namelen; + } else { + struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll; + + msg->msg_namelen = sll->sll_halen + + offsetof(struct sockaddr_ll, sll_addr); ++ copy_len = msg->msg_namelen; ++ if (msg->msg_namelen < sizeof(struct sockaddr_ll)) { ++ memset(msg->msg_name + ++ offsetof(struct sockaddr_ll, sll_addr), ++ 0, sizeof(sll->sll_addr)); ++ msg->msg_namelen = sizeof(struct sockaddr_ll); ++ } + } +- memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, +- msg->msg_namelen); ++ memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, copy_len); + } + + if (pkt_sk(sk)->auxdata) { diff --git a/queue-5.0/packet-validate-msg_namelen-in-send-directly.patch b/queue-5.0/packet-validate-msg_namelen-in-send-directly.patch new file mode 100644 index 00000000000..a241af3ef4f --- /dev/null +++ b/queue-5.0/packet-validate-msg_namelen-in-send-directly.patch @@ -0,0 +1,97 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Willem de Bruijn +Date: Mon, 29 Apr 2019 11:53:18 -0400 +Subject: packet: validate msg_namelen in send directly + +From: Willem de Bruijn + +[ Upstream commit 486efdc8f6ce802b27e15921d2353cc740c55451 ] + +Packet sockets in datagram mode take a destination address. Verify its +length before passing to dev_hard_header. + +Prior to 2.6.14-rc3, the send code ignored sll_halen. This is +established behavior. Directly compare msg_namelen to dev->addr_len. + +Change v1->v2: initialize addr in all paths + +Fixes: 6b8d95f1795c4 ("packet: validate address length if non-zero") +Suggested-by: David Laight +Signed-off-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/packet/af_packet.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -2603,8 +2603,8 @@ static int tpacket_snd(struct packet_soc + void *ph; + DECLARE_SOCKADDR(struct sockaddr_ll *, saddr, msg->msg_name); + bool need_wait = !(msg->msg_flags & MSG_DONTWAIT); ++ unsigned char *addr = NULL; + int tp_len, size_max; +- unsigned char *addr; + void *data; + int len_sum = 0; + int status = TP_STATUS_AVAILABLE; +@@ -2615,7 +2615,6 @@ static int tpacket_snd(struct packet_soc + if (likely(saddr == NULL)) { + dev = packet_cached_dev_get(po); + proto = po->num; +- addr = NULL; + } else { + err = -EINVAL; + if (msg->msg_namelen < sizeof(struct sockaddr_ll)) +@@ -2625,10 +2624,13 @@ static int tpacket_snd(struct packet_soc + sll_addr))) + goto out; + proto = saddr->sll_protocol; +- addr = saddr->sll_halen ? saddr->sll_addr : NULL; + dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); +- if (addr && dev && saddr->sll_halen < dev->addr_len) +- goto out_put; ++ if (po->sk.sk_socket->type == SOCK_DGRAM) { ++ if (dev && msg->msg_namelen < dev->addr_len + ++ offsetof(struct sockaddr_ll, sll_addr)) ++ goto out_put; ++ addr = saddr->sll_addr; ++ } + } + + err = -ENXIO; +@@ -2800,7 +2802,7 @@ static int packet_snd(struct socket *soc + struct sk_buff *skb; + struct net_device *dev; + __be16 proto; +- unsigned char *addr; ++ unsigned char *addr = NULL; + int err, reserve = 0; + struct sockcm_cookie sockc; + struct virtio_net_hdr vnet_hdr = { 0 }; +@@ -2817,7 +2819,6 @@ static int packet_snd(struct socket *soc + if (likely(saddr == NULL)) { + dev = packet_cached_dev_get(po); + proto = po->num; +- addr = NULL; + } else { + err = -EINVAL; + if (msg->msg_namelen < sizeof(struct sockaddr_ll)) +@@ -2825,10 +2826,13 @@ static int packet_snd(struct socket *soc + if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) + goto out; + proto = saddr->sll_protocol; +- addr = saddr->sll_halen ? saddr->sll_addr : NULL; + dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); +- if (addr && dev && saddr->sll_halen < dev->addr_len) +- goto out_unlock; ++ if (sock->type == SOCK_DGRAM) { ++ if (dev && msg->msg_namelen < dev->addr_len + ++ offsetof(struct sockaddr_ll, sll_addr)) ++ goto out_unlock; ++ addr = saddr->sll_addr; ++ } + } + + err = -ENXIO; diff --git a/queue-5.0/rxrpc-fix-net-namespace-cleanup.patch b/queue-5.0/rxrpc-fix-net-namespace-cleanup.patch new file mode 100644 index 00000000000..b281596a69a --- /dev/null +++ b/queue-5.0/rxrpc-fix-net-namespace-cleanup.patch @@ -0,0 +1,92 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: David Howells +Date: Tue, 30 Apr 2019 08:34:08 +0100 +Subject: rxrpc: Fix net namespace cleanup + +From: David Howells + +[ Upstream commit b13023421b5179413421333f602850914f6a7ad8 ] + +In rxrpc_destroy_all_calls(), there are two phases: (1) make sure the +->calls list is empty, emitting error messages if not, and (2) wait for the +RCU cleanup to happen on outstanding calls (ie. ->nr_calls becomes 0). + +To avoid taking the call_lock, the function prechecks ->calls and if empty, +it returns to avoid taking the lock - this is wrong, however: it still +needs to go and do the second phase and wait for ->nr_calls to become 0. + +Without this, the rxrpc_net struct may get deallocated before we get to the +RCU cleanup for the last calls. This can lead to: + + Slab corruption (Not tainted): kmalloc-16k start=ffff88802b178000, len=16384 + 050: 6b 6b 6b 6b 6b 6b 6b 6b 61 6b 6b 6b 6b 6b 6b 6b kkkkkkkkakkkkkkk + +Note the "61" at offset 0x58. This corresponds to the ->nr_calls member of +struct rxrpc_net (which is >9k in size, and thus allocated out of the 16k +slab). + +Fix this by flipping the condition on the if-statement, putting the locked +section inside the if-body and dropping the return from there. The +function will then always go on to wait for the RCU cleanup on outstanding +calls. + +Fixes: 2baec2c3f854 ("rxrpc: Support network namespacing") +Signed-off-by: David Howells +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/rxrpc/call_object.c | 38 +++++++++++++++++++------------------- + 1 file changed, 19 insertions(+), 19 deletions(-) + +--- a/net/rxrpc/call_object.c ++++ b/net/rxrpc/call_object.c +@@ -604,30 +604,30 @@ void rxrpc_destroy_all_calls(struct rxrp + + _enter(""); + +- if (list_empty(&rxnet->calls)) +- return; +- +- write_lock(&rxnet->call_lock); ++ if (!list_empty(&rxnet->calls)) { ++ write_lock(&rxnet->call_lock); + +- while (!list_empty(&rxnet->calls)) { +- call = list_entry(rxnet->calls.next, struct rxrpc_call, link); +- _debug("Zapping call %p", call); +- +- rxrpc_see_call(call); +- list_del_init(&call->link); +- +- pr_err("Call %p still in use (%d,%s,%lx,%lx)!\n", +- call, atomic_read(&call->usage), +- rxrpc_call_states[call->state], +- call->flags, call->events); ++ while (!list_empty(&rxnet->calls)) { ++ call = list_entry(rxnet->calls.next, ++ struct rxrpc_call, link); ++ _debug("Zapping call %p", call); ++ ++ rxrpc_see_call(call); ++ list_del_init(&call->link); ++ ++ pr_err("Call %p still in use (%d,%s,%lx,%lx)!\n", ++ call, atomic_read(&call->usage), ++ rxrpc_call_states[call->state], ++ call->flags, call->events); ++ ++ write_unlock(&rxnet->call_lock); ++ cond_resched(); ++ write_lock(&rxnet->call_lock); ++ } + + write_unlock(&rxnet->call_lock); +- cond_resched(); +- write_lock(&rxnet->call_lock); + } + +- write_unlock(&rxnet->call_lock); +- + atomic_dec(&rxnet->nr_calls); + wait_var_event(&rxnet->nr_calls, !atomic_read(&rxnet->nr_calls)); + } diff --git a/queue-5.0/sctp-avoid-running-the-sctp-state-machine-recursively.patch b/queue-5.0/sctp-avoid-running-the-sctp-state-machine-recursively.patch new file mode 100644 index 00000000000..4e1b9415073 --- /dev/null +++ b/queue-5.0/sctp-avoid-running-the-sctp-state-machine-recursively.patch @@ -0,0 +1,165 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Xin Long +Date: Mon, 29 Apr 2019 14:16:19 +0800 +Subject: sctp: avoid running the sctp state machine recursively + +From: Xin Long + +[ Upstream commit fbd019737d71e405f86549fd738f81e2ff3dd073 ] + +Ying triggered a call trace when doing an asconf testing: + + BUG: scheduling while atomic: swapper/12/0/0x10000100 + Call Trace: + [] dump_stack+0x19/0x1b + [] __schedule_bug+0x64/0x72 + [] __schedule+0x9ba/0xa00 + [] __cond_resched+0x26/0x30 + [] _cond_resched+0x3a/0x50 + [] kmem_cache_alloc_node+0x38/0x200 + [] __alloc_skb+0x5d/0x2d0 + [] sctp_packet_transmit+0x610/0xa20 [sctp] + [] sctp_outq_flush+0x2ce/0xc00 [sctp] + [] sctp_outq_uncork+0x1c/0x20 [sctp] + [] sctp_cmd_interpreter.isra.22+0xc8/0x1460 [sctp] + [] sctp_do_sm+0xe1/0x350 [sctp] + [] sctp_primitive_ASCONF+0x3d/0x50 [sctp] + [] sctp_cmd_interpreter.isra.22+0x114/0x1460 [sctp] + [] sctp_do_sm+0xe1/0x350 [sctp] + [] sctp_assoc_bh_rcv+0xf4/0x1b0 [sctp] + [] sctp_inq_push+0x51/0x70 [sctp] + [] sctp_rcv+0xa8b/0xbd0 [sctp] + +As it shows, the first sctp_do_sm() running under atomic context (NET_RX +softirq) invoked sctp_primitive_ASCONF() that uses GFP_KERNEL flag later, +and this flag is supposed to be used in non-atomic context only. Besides, +sctp_do_sm() was called recursively, which is not expected. + +Vlad tried to fix this recursive call in Commit c0786693404c ("sctp: Fix +oops when sending queued ASCONF chunks") by introducing a new command +SCTP_CMD_SEND_NEXT_ASCONF. But it didn't work as this command is still +used in the first sctp_do_sm() call, and sctp_primitive_ASCONF() will +be called in this command again. + +To avoid calling sctp_do_sm() recursively, we send the next queued ASCONF +not by sctp_primitive_ASCONF(), but by sctp_sf_do_prm_asconf() in the 1st +sctp_do_sm() directly. + +Reported-by: Ying Xu +Signed-off-by: Xin Long +Acked-by: Neil Horman +Acked-by: Marcelo Ricardo Leitner +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/sctp/command.h | 1 - + net/sctp/sm_sideeffect.c | 29 ----------------------------- + net/sctp/sm_statefuns.c | 35 +++++++++++++++++++++++++++-------- + 3 files changed, 27 insertions(+), 38 deletions(-) + +--- a/include/net/sctp/command.h ++++ b/include/net/sctp/command.h +@@ -105,7 +105,6 @@ enum sctp_verb { + SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */ + SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ + SCTP_CMD_SEND_MSG, /* Send the whole use message */ +- SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */ + SCTP_CMD_PURGE_ASCONF_QUEUE, /* Purge all asconf queues.*/ + SCTP_CMD_SET_ASOC, /* Restore association context */ + SCTP_CMD_LAST +--- a/net/sctp/sm_sideeffect.c ++++ b/net/sctp/sm_sideeffect.c +@@ -1112,32 +1112,6 @@ static void sctp_cmd_send_msg(struct sct + } + + +-/* Sent the next ASCONF packet currently stored in the association. +- * This happens after the ASCONF_ACK was succeffully processed. +- */ +-static void sctp_cmd_send_asconf(struct sctp_association *asoc) +-{ +- struct net *net = sock_net(asoc->base.sk); +- +- /* Send the next asconf chunk from the addip chunk +- * queue. +- */ +- if (!list_empty(&asoc->addip_chunk_list)) { +- struct list_head *entry = asoc->addip_chunk_list.next; +- struct sctp_chunk *asconf = list_entry(entry, +- struct sctp_chunk, list); +- list_del_init(entry); +- +- /* Hold the chunk until an ASCONF_ACK is received. */ +- sctp_chunk_hold(asconf); +- if (sctp_primitive_ASCONF(net, asoc, asconf)) +- sctp_chunk_free(asconf); +- else +- asoc->addip_last_asconf = asconf; +- } +-} +- +- + /* These three macros allow us to pull the debugging code out of the + * main flow of sctp_do_sm() to keep attention focused on the real + * functionality there. +@@ -1783,9 +1757,6 @@ static int sctp_cmd_interpreter(enum sct + } + sctp_cmd_send_msg(asoc, cmd->obj.msg, gfp); + break; +- case SCTP_CMD_SEND_NEXT_ASCONF: +- sctp_cmd_send_asconf(asoc); +- break; + case SCTP_CMD_PURGE_ASCONF_QUEUE: + sctp_asconf_queue_teardown(asoc); + break; +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -3824,6 +3824,29 @@ enum sctp_disposition sctp_sf_do_asconf( + return SCTP_DISPOSITION_CONSUME; + } + ++static enum sctp_disposition sctp_send_next_asconf( ++ struct net *net, ++ const struct sctp_endpoint *ep, ++ struct sctp_association *asoc, ++ const union sctp_subtype type, ++ struct sctp_cmd_seq *commands) ++{ ++ struct sctp_chunk *asconf; ++ struct list_head *entry; ++ ++ if (list_empty(&asoc->addip_chunk_list)) ++ return SCTP_DISPOSITION_CONSUME; ++ ++ entry = asoc->addip_chunk_list.next; ++ asconf = list_entry(entry, struct sctp_chunk, list); ++ ++ list_del_init(entry); ++ sctp_chunk_hold(asconf); ++ asoc->addip_last_asconf = asconf; ++ ++ return sctp_sf_do_prm_asconf(net, ep, asoc, type, asconf, commands); ++} ++ + /* + * ADDIP Section 4.3 General rules for address manipulation + * When building TLV parameters for the ASCONF Chunk that will add or +@@ -3915,14 +3938,10 @@ enum sctp_disposition sctp_sf_do_asconf_ + SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); + + if (!sctp_process_asconf_ack((struct sctp_association *)asoc, +- asconf_ack)) { +- /* Successfully processed ASCONF_ACK. We can +- * release the next asconf if we have one. +- */ +- sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF, +- SCTP_NULL()); +- return SCTP_DISPOSITION_CONSUME; +- } ++ asconf_ack)) ++ return sctp_send_next_asconf(net, ep, ++ (struct sctp_association *)asoc, ++ type, commands); + + abort = sctp_make_abort(asoc, asconf_ack, + sizeof(struct sctp_errhdr)); diff --git a/queue-5.0/selftests-fib_rule_tests-fix-icmp-proto-with-ipv6.patch b/queue-5.0/selftests-fib_rule_tests-fix-icmp-proto-with-ipv6.patch new file mode 100644 index 00000000000..36221405722 --- /dev/null +++ b/queue-5.0/selftests-fib_rule_tests-fix-icmp-proto-with-ipv6.patch @@ -0,0 +1,33 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: David Ahern +Date: Mon, 29 Apr 2019 10:30:09 -0700 +Subject: selftests: fib_rule_tests: Fix icmp proto with ipv6 + +From: David Ahern + +[ Upstream commit 15d55bae4e3c43cd9f87fd93c73a263e172d34e1 ] + +A recent commit returns an error if icmp is used as the ip-proto for +IPv6 fib rules. Update fib_rule_tests to send ipv6-icmp instead of icmp. + +Fixes: 5e1a99eae8499 ("ipv4: Add ICMPv6 support when parse route ipproto") +Signed-off-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/net/fib_rule_tests.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/tools/testing/selftests/net/fib_rule_tests.sh ++++ b/tools/testing/selftests/net/fib_rule_tests.sh +@@ -148,8 +148,8 @@ fib_rule6_test() + + fib_check_iproute_support "ipproto" "ipproto" + if [ $? -eq 0 ]; then +- match="ipproto icmp" +- fib_rule6_test_match_n_redirect "$match" "$match" "ipproto icmp match" ++ match="ipproto ipv6-icmp" ++ fib_rule6_test_match_n_redirect "$match" "$match" "ipproto ipv6-icmp match" + fi + } + diff --git a/queue-5.0/selftests-fib_rule_tests-print-the-result-and-return-1-if-any-tests-failed.patch b/queue-5.0/selftests-fib_rule_tests-print-the-result-and-return-1-if-any-tests-failed.patch new file mode 100644 index 00000000000..4058564f3e7 --- /dev/null +++ b/queue-5.0/selftests-fib_rule_tests-print-the-result-and-return-1-if-any-tests-failed.patch @@ -0,0 +1,38 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Hangbin Liu +Date: Tue, 30 Apr 2019 10:46:10 +0800 +Subject: selftests: fib_rule_tests: print the result and return 1 if any tests failed + +From: Hangbin Liu + +[ Upstream commit f68d7c44e76532e46f292ad941aa3706cb9e6e40 ] + +Fixes: 65b2b4939a64 ("selftests: net: initial fib rule tests") +Signed-off-by: Hangbin Liu +Reviewed-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/net/fib_rule_tests.sh | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/tools/testing/selftests/net/fib_rule_tests.sh ++++ b/tools/testing/selftests/net/fib_rule_tests.sh +@@ -27,6 +27,7 @@ log_test() + nsuccess=$((nsuccess+1)) + printf "\n TEST: %-50s [ OK ]\n" "${msg}" + else ++ ret=1 + nfail=$((nfail+1)) + printf "\n TEST: %-50s [FAIL]\n" "${msg}" + if [ "${PAUSE_ON_FAIL}" = "yes" ]; then +@@ -245,4 +246,9 @@ setup + run_fibrule_tests + cleanup + ++if [ "$TESTS" != "none" ]; then ++ printf "\nTests passed: %3d\n" ${nsuccess} ++ printf "Tests failed: %3d\n" ${nfail} ++fi ++ + exit $ret diff --git a/queue-5.0/tcp-add-sanity-tests-in-tcp_add_backlog.patch b/queue-5.0/tcp-add-sanity-tests-in-tcp_add_backlog.patch new file mode 100644 index 00000000000..cde3c28e5dd --- /dev/null +++ b/queue-5.0/tcp-add-sanity-tests-in-tcp_add_backlog.patch @@ -0,0 +1,69 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Eric Dumazet +Date: Fri, 26 Apr 2019 10:10:05 -0700 +Subject: tcp: add sanity tests in tcp_add_backlog() + +From: Eric Dumazet + +[ Upstream commit ca2fe2956acef2f87f6c55549874fdd2e92d9824 ] + +Richard and Bruno both reported that my commit added a bug, +and Bruno was able to determine the problem came when a segment +wih a FIN packet was coalesced to a prior one in tcp backlog queue. + +It turns out the header prediction in tcp_rcv_established() +looks back to TCP headers in the packet, not in the metadata +(aka TCP_SKB_CB(skb)->tcp_flags) + +The fast path in tcp_rcv_established() is not supposed to +handle a FIN flag (it does not call tcp_fin()) + +Therefore we need to make sure to propagate the FIN flag, +so that the coalesced packet does not go through the fast path, +the same than a GRO packet carrying a FIN flag. + +While we are at it, make sure we do not coalesce packets with +RST or SYN, or if they do not have ACK set. + +Many thanks to Richard and Bruno for pinpointing the bad commit, +and to Richard for providing a first version of the fix. + +Fixes: 4f693b55c3d2 ("tcp: implement coalescing on backlog queue") +Signed-off-by: Eric Dumazet +Reported-by: Richard Purdie +Reported-by: Bruno Prémont +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_ipv4.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -1673,7 +1673,9 @@ bool tcp_add_backlog(struct sock *sk, st + if (TCP_SKB_CB(tail)->end_seq != TCP_SKB_CB(skb)->seq || + TCP_SKB_CB(tail)->ip_dsfield != TCP_SKB_CB(skb)->ip_dsfield || + ((TCP_SKB_CB(tail)->tcp_flags | +- TCP_SKB_CB(skb)->tcp_flags) & TCPHDR_URG) || ++ TCP_SKB_CB(skb)->tcp_flags) & (TCPHDR_SYN | TCPHDR_RST | TCPHDR_URG)) || ++ !((TCP_SKB_CB(tail)->tcp_flags & ++ TCP_SKB_CB(skb)->tcp_flags) & TCPHDR_ACK) || + ((TCP_SKB_CB(tail)->tcp_flags ^ + TCP_SKB_CB(skb)->tcp_flags) & (TCPHDR_ECE | TCPHDR_CWR)) || + #ifdef CONFIG_TLS_DEVICE +@@ -1692,6 +1694,15 @@ bool tcp_add_backlog(struct sock *sk, st + if (after(TCP_SKB_CB(skb)->ack_seq, TCP_SKB_CB(tail)->ack_seq)) + TCP_SKB_CB(tail)->ack_seq = TCP_SKB_CB(skb)->ack_seq; + ++ /* We have to update both TCP_SKB_CB(tail)->tcp_flags and ++ * thtail->fin, so that the fast path in tcp_rcv_established() ++ * is not entered if we append a packet with a FIN. ++ * SYN, RST, URG are not present. ++ * ACK is set on both packets. ++ * PSH : we do not really care in TCP stack, ++ * at least for 'GRO' packets. ++ */ ++ thtail->fin |= th->fin; + TCP_SKB_CB(tail)->tcp_flags |= TCP_SKB_CB(skb)->tcp_flags; + + if (TCP_SKB_CB(skb)->has_rxtstamp) { diff --git a/queue-5.0/udp-fix-gro-packet-of-death.patch b/queue-5.0/udp-fix-gro-packet-of-death.patch new file mode 100644 index 00000000000..5dc6d2dbbfc --- /dev/null +++ b/queue-5.0/udp-fix-gro-packet-of-death.patch @@ -0,0 +1,183 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Eric Dumazet +Date: Wed, 1 May 2019 18:56:28 -0700 +Subject: udp: fix GRO packet of death + +From: Eric Dumazet + +[ Upstream commit 4dd2b82d5adfbe0b1587ccad7a8f76d826120f37 ] + +syzbot was able to crash host by sending UDP packets with a 0 payload. + +TCP does not have this issue since we do not aggregate packets without +payload. + +Since dev_gro_receive() sets gso_size based on skb_gro_len(skb) +it seems not worth trying to cope with padded packets. + +BUG: KASAN: slab-out-of-bounds in skb_gro_receive+0xf5f/0x10e0 net/core/skbuff.c:3826 +Read of size 16 at addr ffff88808893fff0 by task syz-executor612/7889 + +CPU: 0 PID: 7889 Comm: syz-executor612 Not tainted 5.1.0-rc7+ #96 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x172/0x1f0 lib/dump_stack.c:113 + print_address_description.cold+0x7c/0x20d mm/kasan/report.c:187 + kasan_report.cold+0x1b/0x40 mm/kasan/report.c:317 + __asan_report_load16_noabort+0x14/0x20 mm/kasan/generic_report.c:133 + skb_gro_receive+0xf5f/0x10e0 net/core/skbuff.c:3826 + udp_gro_receive_segment net/ipv4/udp_offload.c:382 [inline] + call_gro_receive include/linux/netdevice.h:2349 [inline] + udp_gro_receive+0xb61/0xfd0 net/ipv4/udp_offload.c:414 + udp4_gro_receive+0x763/0xeb0 net/ipv4/udp_offload.c:478 + inet_gro_receive+0xe72/0x1110 net/ipv4/af_inet.c:1510 + dev_gro_receive+0x1cd0/0x23c0 net/core/dev.c:5581 + napi_gro_frags+0x36b/0xd10 net/core/dev.c:5843 + tun_get_user+0x2f24/0x3fb0 drivers/net/tun.c:1981 + tun_chr_write_iter+0xbd/0x156 drivers/net/tun.c:2027 + call_write_iter include/linux/fs.h:1866 [inline] + do_iter_readv_writev+0x5e1/0x8e0 fs/read_write.c:681 + do_iter_write fs/read_write.c:957 [inline] + do_iter_write+0x184/0x610 fs/read_write.c:938 + vfs_writev+0x1b3/0x2f0 fs/read_write.c:1002 + do_writev+0x15e/0x370 fs/read_write.c:1037 + __do_sys_writev fs/read_write.c:1110 [inline] + __se_sys_writev fs/read_write.c:1107 [inline] + __x64_sys_writev+0x75/0xb0 fs/read_write.c:1107 + do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290 + entry_SYSCALL_64_after_hwframe+0x49/0xbe +RIP: 0033:0x441cc0 +Code: 05 48 3d 01 f0 ff ff 0f 83 9d 09 fc ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 83 3d 51 93 29 00 00 75 14 b8 14 00 00 00 0f 05 <48> 3d 01 f0 ff ff 0f 83 74 09 fc ff c3 48 83 ec 08 e8 ba 2b 00 00 +RSP: 002b:00007ffe8c716118 EFLAGS: 00000246 ORIG_RAX: 0000000000000014 +RAX: ffffffffffffffda RBX: 00007ffe8c716150 RCX: 0000000000441cc0 +RDX: 0000000000000001 RSI: 00007ffe8c716170 RDI: 00000000000000f0 +RBP: 0000000000000000 R08: 000000000000ffff R09: 0000000000a64668 +R10: 0000000020000040 R11: 0000000000000246 R12: 000000000000c2d9 +R13: 0000000000402b50 R14: 0000000000000000 R15: 0000000000000000 + +Allocated by task 5143: + save_stack+0x45/0xd0 mm/kasan/common.c:75 + set_track mm/kasan/common.c:87 [inline] + __kasan_kmalloc mm/kasan/common.c:497 [inline] + __kasan_kmalloc.constprop.0+0xcf/0xe0 mm/kasan/common.c:470 + kasan_slab_alloc+0xf/0x20 mm/kasan/common.c:505 + slab_post_alloc_hook mm/slab.h:437 [inline] + slab_alloc mm/slab.c:3393 [inline] + kmem_cache_alloc+0x11a/0x6f0 mm/slab.c:3555 + mm_alloc+0x1d/0xd0 kernel/fork.c:1030 + bprm_mm_init fs/exec.c:363 [inline] + __do_execve_file.isra.0+0xaa3/0x23f0 fs/exec.c:1791 + do_execveat_common fs/exec.c:1865 [inline] + do_execve fs/exec.c:1882 [inline] + __do_sys_execve fs/exec.c:1958 [inline] + __se_sys_execve fs/exec.c:1953 [inline] + __x64_sys_execve+0x8f/0xc0 fs/exec.c:1953 + do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +Freed by task 5351: + save_stack+0x45/0xd0 mm/kasan/common.c:75 + set_track mm/kasan/common.c:87 [inline] + __kasan_slab_free+0x102/0x150 mm/kasan/common.c:459 + kasan_slab_free+0xe/0x10 mm/kasan/common.c:467 + __cache_free mm/slab.c:3499 [inline] + kmem_cache_free+0x86/0x260 mm/slab.c:3765 + __mmdrop+0x238/0x320 kernel/fork.c:677 + mmdrop include/linux/sched/mm.h:49 [inline] + finish_task_switch+0x47b/0x780 kernel/sched/core.c:2746 + context_switch kernel/sched/core.c:2880 [inline] + __schedule+0x81b/0x1cc0 kernel/sched/core.c:3518 + preempt_schedule_irq+0xb5/0x140 kernel/sched/core.c:3745 + retint_kernel+0x1b/0x2d + arch_local_irq_restore arch/x86/include/asm/paravirt.h:767 [inline] + kmem_cache_free+0xab/0x260 mm/slab.c:3766 + anon_vma_chain_free mm/rmap.c:134 [inline] + unlink_anon_vmas+0x2ba/0x870 mm/rmap.c:401 + free_pgtables+0x1af/0x2f0 mm/memory.c:394 + exit_mmap+0x2d1/0x530 mm/mmap.c:3144 + __mmput kernel/fork.c:1046 [inline] + mmput+0x15f/0x4c0 kernel/fork.c:1067 + exec_mmap fs/exec.c:1046 [inline] + flush_old_exec+0x8d9/0x1c20 fs/exec.c:1279 + load_elf_binary+0x9bc/0x53f0 fs/binfmt_elf.c:864 + search_binary_handler fs/exec.c:1656 [inline] + search_binary_handler+0x17f/0x570 fs/exec.c:1634 + exec_binprm fs/exec.c:1698 [inline] + __do_execve_file.isra.0+0x1394/0x23f0 fs/exec.c:1818 + do_execveat_common fs/exec.c:1865 [inline] + do_execve fs/exec.c:1882 [inline] + __do_sys_execve fs/exec.c:1958 [inline] + __se_sys_execve fs/exec.c:1953 [inline] + __x64_sys_execve+0x8f/0xc0 fs/exec.c:1953 + do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +The buggy address belongs to the object at ffff88808893f7c0 + which belongs to the cache mm_struct of size 1496 +The buggy address is located 600 bytes to the right of + 1496-byte region [ffff88808893f7c0, ffff88808893fd98) +The buggy address belongs to the page: +page:ffffea0002224f80 count:1 mapcount:0 mapping:ffff88821bc40ac0 index:0xffff88808893f7c0 compound_mapcount: 0 +flags: 0x1fffc0000010200(slab|head) +raw: 01fffc0000010200 ffffea00025b4f08 ffffea00027b9d08 ffff88821bc40ac0 +raw: ffff88808893f7c0 ffff88808893e440 0000000100000001 0000000000000000 +page dumped because: kasan: bad access detected + +Memory state around the buggy address: + ffff88808893fe80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + ffff88808893ff00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +>ffff88808893ff80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + ^ + ffff888088940000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + ffff888088940080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +Fixes: e20cf8d3f1f7 ("udp: implement GRO for plain UDP sockets.") +Signed-off-by: Eric Dumazet +Cc: Paolo Abeni +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/udp_offload.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -352,6 +352,7 @@ static struct sk_buff *udp_gro_receive_s + struct sk_buff *pp = NULL; + struct udphdr *uh2; + struct sk_buff *p; ++ unsigned int ulen; + + /* requires non zero csum, for symmetry with GSO */ + if (!uh->check) { +@@ -359,6 +360,12 @@ static struct sk_buff *udp_gro_receive_s + return NULL; + } + ++ /* Do not deal with padded or malicious packets, sorry ! */ ++ ulen = ntohs(uh->len); ++ if (ulen <= sizeof(*uh) || ulen != skb_gro_len(skb)) { ++ NAPI_GRO_CB(skb)->flush = 1; ++ return NULL; ++ } + /* pull encapsulating udp header */ + skb_gro_pull(skb, sizeof(struct udphdr)); + skb_gro_postpull_rcsum(skb, uh, sizeof(struct udphdr)); +@@ -377,12 +384,12 @@ static struct sk_buff *udp_gro_receive_s + + /* Terminate the flow on len mismatch or if it grow "too much". + * Under small packet flood GRO count could elsewhere grow a lot +- * leading to execessive truesize values. ++ * leading to excessive truesize values. + * On len mismatch merge the first packet shorter than gso_size, + * otherwise complete the GRO packet. + */ +- if (uh->len > uh2->len || skb_gro_receive(p, skb) || +- uh->len != uh2->len || ++ if (ulen > ntohs(uh2->len) || skb_gro_receive(p, skb) || ++ ulen != ntohs(uh2->len) || + NAPI_GRO_CB(p)->count >= UDP_GRO_CNT_MAX) + pp = p; + diff --git a/queue-5.0/udp-fix-gro-reception-in-case-of-length-mismatch.patch b/queue-5.0/udp-fix-gro-reception-in-case-of-length-mismatch.patch new file mode 100644 index 00000000000..3183f645691 --- /dev/null +++ b/queue-5.0/udp-fix-gro-reception-in-case-of-length-mismatch.patch @@ -0,0 +1,47 @@ +From foo@baz Sat 04 May 2019 09:23:26 AM CEST +From: Paolo Abeni +Date: Fri, 26 Apr 2019 12:50:44 +0200 +Subject: udp: fix GRO reception in case of length mismatch + +From: Paolo Abeni + +[ Upstream commit 21f1b8a6636c4dbde4aa1ec0343f42eaf653ffcc ] + +Currently, the UDP GRO code path does bad things on some edge +conditions - Aggregation can happen even on packet with different +lengths. + +Fix the above by rewriting the 'complete' condition for GRO +packets. While at it, note explicitly that we allow merging the +first packet per burst below gso_size. + +Reported-by: Sean Tong +Fixes: e20cf8d3f1f7 ("udp: implement GRO for plain UDP sockets.") +Signed-off-by: Paolo Abeni +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/udp_offload.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -377,13 +377,14 @@ static struct sk_buff *udp_gro_receive_s + + /* Terminate the flow on len mismatch or if it grow "too much". + * Under small packet flood GRO count could elsewhere grow a lot +- * leading to execessive truesize values ++ * leading to execessive truesize values. ++ * On len mismatch merge the first packet shorter than gso_size, ++ * otherwise complete the GRO packet. + */ +- if (!skb_gro_receive(p, skb) && ++ if (uh->len > uh2->len || skb_gro_receive(p, skb) || ++ uh->len != uh2->len || + NAPI_GRO_CB(p)->count >= UDP_GRO_CNT_MAX) + pp = p; +- else if (uh->len != uh2->len) +- pp = p; + + return pp; + }