From: Greg Kroah-Hartman Date: Sat, 10 Apr 2021 14:31:45 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v4.19.187~63 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4a28f30ab64826eb10a92208ab1ede6ff90e2be5;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: batman-adv-initialize-struct-batadv_tvlv_tt_vlan_data-reserved-field.patch bpf-sockmap-fix-sk-prot-unhash-op-reset.patch ethernet-netronome-nfp-fix-a-use-after-free-in-nfp_bpf_ctrl_msg_rx.patch i40e-fix-sparse-error-vsi-netdev-could-be-null.patch i40e-fix-sparse-warning-missing-error-code-err.patch ice-cleanup-fltr-list-in-case-of-allocation-issues.patch ice-fix-for-dereference-of-null-pointer.patch ice-increase-control-queue-timeout.patch mac80211-fix-txq-ac-confusion.patch net-ensure-mac-header-is-set-in-virtio_net_hdr_to_skb.patch net-hso-fix-null-ptr-deref-during-tty-device-unregistration.patch net-hsr-reset-mac-header-for-tx-path.patch net-ipv6-bugfix-raw-sctp-switch-to-ipv6_can_nonlocal_bind.patch net-let-skb_orphan_partial-wake-up-waiters.patch net-sched-fix-action-overwrite-reference-counting.patch net-sched-sch_teql-fix-null-pointer-dereference.patch --- diff --git a/queue-5.4/batman-adv-initialize-struct-batadv_tvlv_tt_vlan_data-reserved-field.patch b/queue-5.4/batman-adv-initialize-struct-batadv_tvlv_tt_vlan_data-reserved-field.patch new file mode 100644 index 00000000000..77a43732250 --- /dev/null +++ b/queue-5.4/batman-adv-initialize-struct-batadv_tvlv_tt_vlan_data-reserved-field.patch @@ -0,0 +1,48 @@ +From 08c27f3322fec11950b8f1384aa0f3b11d028528 Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Mon, 5 Apr 2021 19:16:50 +0900 +Subject: batman-adv: initialize "struct batadv_tvlv_tt_vlan_data"->reserved field + +From: Tetsuo Handa + +commit 08c27f3322fec11950b8f1384aa0f3b11d028528 upstream. + +KMSAN found uninitialized value at batadv_tt_prepare_tvlv_local_data() +[1], for commit ced72933a5e8ab52 ("batman-adv: use CRC32C instead of CRC16 +in TT code") inserted 'reserved' field into "struct batadv_tvlv_tt_data" +and commit 7ea7b4a142758dea ("batman-adv: make the TT CRC logic VLAN +specific") moved that field to "struct batadv_tvlv_tt_vlan_data" but left +that field uninitialized. + +[1] https://syzkaller.appspot.com/bug?id=07f3e6dba96f0eb3cabab986adcd8a58b9bdbe9d + +Reported-by: syzbot +Tested-by: syzbot +Signed-off-by: Tetsuo Handa +Fixes: ced72933a5e8ab52 ("batman-adv: use CRC32C instead of CRC16 in TT code") +Fixes: 7ea7b4a142758dea ("batman-adv: make the TT CRC logic VLAN specific") +Acked-by: Sven Eckelmann +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/translation-table.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/batman-adv/translation-table.c ++++ b/net/batman-adv/translation-table.c +@@ -891,6 +891,7 @@ batadv_tt_prepare_tvlv_global_data(struc + hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) { + tt_vlan->vid = htons(vlan->vid); + tt_vlan->crc = htonl(vlan->tt.crc); ++ tt_vlan->reserved = 0; + + tt_vlan++; + } +@@ -974,6 +975,7 @@ batadv_tt_prepare_tvlv_local_data(struct + + tt_vlan->vid = htons(vlan->vid); + tt_vlan->crc = htonl(vlan->tt.crc); ++ tt_vlan->reserved = 0; + + tt_vlan++; + } diff --git a/queue-5.4/bpf-sockmap-fix-sk-prot-unhash-op-reset.patch b/queue-5.4/bpf-sockmap-fix-sk-prot-unhash-op-reset.patch new file mode 100644 index 00000000000..70ed2e8b225 --- /dev/null +++ b/queue-5.4/bpf-sockmap-fix-sk-prot-unhash-op-reset.patch @@ -0,0 +1,87 @@ +From 1c84b33101c82683dee8b06761ca1f69e78c8ee7 Mon Sep 17 00:00:00 2001 +From: John Fastabend +Date: Thu, 1 Apr 2021 15:00:19 -0700 +Subject: bpf, sockmap: Fix sk->prot unhash op reset + +From: John Fastabend + +commit 1c84b33101c82683dee8b06761ca1f69e78c8ee7 upstream. + +In '4da6a196f93b1' we fixed a potential unhash loop caused when +a TLS socket in a sockmap was removed from the sockmap. This +happened because the unhash operation on the TLS ctx continued +to point at the sockmap implementation of unhash even though the +psock has already been removed. The sockmap unhash handler when a +psock is removed does the following, + + void sock_map_unhash(struct sock *sk) + { + void (*saved_unhash)(struct sock *sk); + struct sk_psock *psock; + + rcu_read_lock(); + psock = sk_psock(sk); + if (unlikely(!psock)) { + rcu_read_unlock(); + if (sk->sk_prot->unhash) + sk->sk_prot->unhash(sk); + return; + } + [...] + } + +The unlikely() case is there to handle the case where psock is detached +but the proto ops have not been updated yet. But, in the above case +with TLS and removed psock we never fixed sk_prot->unhash() and unhash() +points back to sock_map_unhash resulting in a loop. To fix this we added +this bit of code, + + static inline void sk_psock_restore_proto(struct sock *sk, + struct sk_psock *psock) + { + sk->sk_prot->unhash = psock->saved_unhash; + +This will set the sk_prot->unhash back to its saved value. This is the +correct callback for a TLS socket that has been removed from the sock_map. +Unfortunately, this also overwrites the unhash pointer for all psocks. +We effectively break sockmap unhash handling for any future socks. +Omitting the unhash operation will leave stale entries in the map if +a socket transition through unhash, but does not do close() op. + +To fix set unhash correctly before calling into tls_update. This way the +TLS enabled socket will point to the saved unhash() handler. + +Fixes: 4da6a196f93b1 ("bpf: Sockmap/tls, during free we may call tcp_bpf_unhash() in loop") +Reported-by: Cong Wang +Reported-by: Lorenz Bauer +Suggested-by: Cong Wang +Signed-off-by: John Fastabend +Signed-off-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/161731441904.68884.15593917809745631972.stgit@john-XPS-13-9370 +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/skmsg.h | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/include/linux/skmsg.h ++++ b/include/linux/skmsg.h +@@ -355,13 +355,17 @@ static inline void sk_psock_update_proto + static inline void sk_psock_restore_proto(struct sock *sk, + struct sk_psock *psock) + { +- sk->sk_prot->unhash = psock->saved_unhash; +- + if (psock->sk_proto) { + struct inet_connection_sock *icsk = inet_csk(sk); + bool has_ulp = !!icsk->icsk_ulp_data; + + if (has_ulp) { ++ /* TLS does not have an unhash proto in SW cases, but we need ++ * to ensure we stop using the sock_map unhash routine because ++ * the associated psock is being removed. So use the original ++ * unhash handler. ++ */ ++ WRITE_ONCE(sk->sk_prot->unhash, psock->saved_unhash); + tcp_update_ulp(sk, psock->sk_proto, + psock->saved_write_space); + } else { diff --git a/queue-5.4/ethernet-netronome-nfp-fix-a-use-after-free-in-nfp_bpf_ctrl_msg_rx.patch b/queue-5.4/ethernet-netronome-nfp-fix-a-use-after-free-in-nfp_bpf_ctrl_msg_rx.patch new file mode 100644 index 00000000000..e63a42fbdc9 --- /dev/null +++ b/queue-5.4/ethernet-netronome-nfp-fix-a-use-after-free-in-nfp_bpf_ctrl_msg_rx.patch @@ -0,0 +1,34 @@ +From 6e5a03bcba44e080a6bf300194a68ce9bb1e5184 Mon Sep 17 00:00:00 2001 +From: Lv Yunlong +Date: Mon, 29 Mar 2021 04:50:02 -0700 +Subject: ethernet/netronome/nfp: Fix a use after free in nfp_bpf_ctrl_msg_rx + +From: Lv Yunlong + +commit 6e5a03bcba44e080a6bf300194a68ce9bb1e5184 upstream. + +In nfp_bpf_ctrl_msg_rx, if +nfp_ccm_get_type(skb) == NFP_CCM_TYPE_BPF_BPF_EVENT is true, the skb +will be freed. But the skb is still used by nfp_ccm_rx(&bpf->ccm, skb). + +My patch adds a return when the skb was freed. + +Fixes: bcf0cafab44fd ("nfp: split out common control message handling code") +Signed-off-by: Lv Yunlong +Reviewed-by: Jakub Kicinski +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/netronome/nfp/bpf/cmsg.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c ++++ b/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c +@@ -454,6 +454,7 @@ void nfp_bpf_ctrl_msg_rx(struct nfp_app + dev_consume_skb_any(skb); + else + dev_kfree_skb_any(skb); ++ return; + } + + nfp_ccm_rx(&bpf->ccm, skb); diff --git a/queue-5.4/i40e-fix-sparse-error-vsi-netdev-could-be-null.patch b/queue-5.4/i40e-fix-sparse-error-vsi-netdev-could-be-null.patch new file mode 100644 index 00000000000..f21f6179d1c --- /dev/null +++ b/queue-5.4/i40e-fix-sparse-error-vsi-netdev-could-be-null.patch @@ -0,0 +1,39 @@ +From 6b5674fe6b9bf05394886ebcec62b2d7dae88c42 Mon Sep 17 00:00:00 2001 +From: Arkadiusz Kubalewski +Date: Fri, 26 Mar 2021 19:43:42 +0100 +Subject: i40e: Fix sparse error: 'vsi->netdev' could be null + +From: Arkadiusz Kubalewski + +commit 6b5674fe6b9bf05394886ebcec62b2d7dae88c42 upstream. + +Remove vsi->netdev->name from the trace. +This is redundant information. With the devinfo trace, the adapter +is already identifiable. + +Previously following error was produced when compiling against sparse. +i40e_main.c:2571 i40e_sync_vsi_filters() error: + we previously assumed 'vsi->netdev' could be null (see line 2323) + +Fixes: b603f9dc20af ("i40e: Log info when PF is entering and leaving Allmulti mode.") +Signed-off-by: Aleksandr Loktionov +Signed-off-by: Arkadiusz Kubalewski +Tested-by: Dave Switzer +Signed-off-by: Tony Nguyen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -2547,8 +2547,7 @@ int i40e_sync_vsi_filters(struct i40e_vs + i40e_stat_str(hw, aq_ret), + i40e_aq_str(hw, hw->aq.asq_last_status)); + } else { +- dev_info(&pf->pdev->dev, "%s is %s allmulti mode.\n", +- vsi->netdev->name, ++ dev_info(&pf->pdev->dev, "%s allmulti mode.\n", + cur_multipromisc ? "entering" : "leaving"); + } + } diff --git a/queue-5.4/i40e-fix-sparse-warning-missing-error-code-err.patch b/queue-5.4/i40e-fix-sparse-warning-missing-error-code-err.patch new file mode 100644 index 00000000000..08f9459fc1c --- /dev/null +++ b/queue-5.4/i40e-fix-sparse-warning-missing-error-code-err.patch @@ -0,0 +1,45 @@ +From 8a1e918d833ca5c391c4ded5dc006e2d1ce6d37c Mon Sep 17 00:00:00 2001 +From: Arkadiusz Kubalewski +Date: Fri, 26 Mar 2021 19:43:43 +0100 +Subject: i40e: Fix sparse warning: missing error code 'err' + +From: Arkadiusz Kubalewski + +commit 8a1e918d833ca5c391c4ded5dc006e2d1ce6d37c upstream. + +Set proper return values inside error checking if-statements. + +Previously following warning was produced when compiling against sparse. +i40e_main.c:15162 i40e_init_recovery_mode() warn: missing error code 'err' + +Fixes: 4ff0ee1af0169 ("i40e: Introduce recovery mode support") +Signed-off-by: Aleksandr Loktionov +Signed-off-by: Arkadiusz Kubalewski +Tested-by: Dave Switzer +Signed-off-by: Tony Nguyen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/i40e/i40e_main.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -14701,12 +14701,16 @@ static int i40e_init_recovery_mode(struc + * in order to register the netdev + */ + v_idx = i40e_vsi_mem_alloc(pf, I40E_VSI_MAIN); +- if (v_idx < 0) ++ if (v_idx < 0) { ++ err = v_idx; + goto err_switch_setup; ++ } + pf->lan_vsi = v_idx; + vsi = pf->vsi[v_idx]; +- if (!vsi) ++ if (!vsi) { ++ err = -EFAULT; + goto err_switch_setup; ++ } + vsi->alloc_queue_pairs = 1; + err = i40e_config_netdev(vsi); + if (err) diff --git a/queue-5.4/ice-cleanup-fltr-list-in-case-of-allocation-issues.patch b/queue-5.4/ice-cleanup-fltr-list-in-case-of-allocation-issues.patch new file mode 100644 index 00000000000..2761691cb67 --- /dev/null +++ b/queue-5.4/ice-cleanup-fltr-list-in-case-of-allocation-issues.patch @@ -0,0 +1,44 @@ +From b7eeb52721fe417730fc5adc5cbeeb5fe349ab26 Mon Sep 17 00:00:00 2001 +From: Robert Malz +Date: Fri, 26 Feb 2021 13:19:32 -0800 +Subject: ice: Cleanup fltr list in case of allocation issues + +From: Robert Malz + +commit b7eeb52721fe417730fc5adc5cbeeb5fe349ab26 upstream. + +When ice_remove_vsi_lkup_fltr is called, by calling +ice_add_to_vsi_fltr_list local copy of vsi filter list +is created. If any issues during creation of vsi filter +list occurs it up for the caller to free already +allocated memory. This patch ensures proper memory +deallocation in these cases. + +Fixes: 80d144c9ac82 ("ice: Refactor switch rule management structures and functions") +Signed-off-by: Robert Malz +Tested-by: Tony Brelinski +Signed-off-by: Tony Nguyen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/ice/ice_switch.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/intel/ice/ice_switch.c ++++ b/drivers/net/ethernet/intel/ice/ice_switch.c +@@ -2665,7 +2665,7 @@ ice_remove_vsi_lkup_fltr(struct ice_hw * + &remove_list_head); + mutex_unlock(rule_lock); + if (status) +- return; ++ goto free_fltr_list; + + switch (lkup) { + case ICE_SW_LKUP_MAC: +@@ -2688,6 +2688,7 @@ ice_remove_vsi_lkup_fltr(struct ice_hw * + break; + } + ++free_fltr_list: + list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) { + list_del(&fm_entry->list_entry); + devm_kfree(ice_hw_to_dev(hw), fm_entry); diff --git a/queue-5.4/ice-fix-for-dereference-of-null-pointer.patch b/queue-5.4/ice-fix-for-dereference-of-null-pointer.patch new file mode 100644 index 00000000000..42d6053965b --- /dev/null +++ b/queue-5.4/ice-fix-for-dereference-of-null-pointer.patch @@ -0,0 +1,67 @@ +From 7a91d3f02b04b2fb18c2dfa8b6c4e5a40a2753f5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jacek=20Bu=C5=82atek?= +Date: Fri, 26 Feb 2021 13:19:29 -0800 +Subject: ice: Fix for dereference of NULL pointer +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jacek Bułatek + +commit 7a91d3f02b04b2fb18c2dfa8b6c4e5a40a2753f5 upstream. + +Add handling of allocation fault for ice_vsi_list_map_info. + +Also *fi should not be NULL pointer, it is a reference to raw +data field, so remove this variable and use the reference +directly. + +Fixes: 9daf8208dd4d ("ice: Add support for switch filter programming") +Signed-off-by: Jacek Bułatek +Co-developed-by: Haiyue Wang +Signed-off-by: Haiyue Wang +Tested-by: Tony Brelinski +Signed-off-by: Tony Nguyen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/ice/ice_switch.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/intel/ice/ice_switch.c ++++ b/drivers/net/ethernet/intel/ice/ice_switch.c +@@ -1279,6 +1279,9 @@ ice_add_update_vsi_list(struct ice_hw *h + ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, + vsi_list_id); + ++ if (!m_entry->vsi_list_info) ++ return ICE_ERR_NO_MEMORY; ++ + /* If this entry was large action then the large action needs + * to be updated to point to FWD to VSI list + */ +@@ -2266,6 +2269,7 @@ ice_vsi_uses_fltr(struct ice_fltr_mgmt_l + return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI && + fm_entry->fltr_info.vsi_handle == vsi_handle) || + (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST && ++ fm_entry->vsi_list_info && + (test_bit(vsi_handle, fm_entry->vsi_list_info->vsi_map)))); + } + +@@ -2338,14 +2342,12 @@ ice_add_to_vsi_fltr_list(struct ice_hw * + return ICE_ERR_PARAM; + + list_for_each_entry(fm_entry, lkup_list_head, list_entry) { +- struct ice_fltr_info *fi; +- +- fi = &fm_entry->fltr_info; +- if (!fi || !ice_vsi_uses_fltr(fm_entry, vsi_handle)) ++ if (!ice_vsi_uses_fltr(fm_entry, vsi_handle)) + continue; + + status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle, +- vsi_list_head, fi); ++ vsi_list_head, ++ &fm_entry->fltr_info); + if (status) + return status; + } diff --git a/queue-5.4/ice-increase-control-queue-timeout.patch b/queue-5.4/ice-increase-control-queue-timeout.patch new file mode 100644 index 00000000000..4c71f29fbfe --- /dev/null +++ b/queue-5.4/ice-increase-control-queue-timeout.patch @@ -0,0 +1,34 @@ +From f88c529ac77b3c21819d2cf1dfcfae1937849743 Mon Sep 17 00:00:00 2001 +From: Fabio Pricoco +Date: Fri, 26 Feb 2021 13:19:24 -0800 +Subject: ice: Increase control queue timeout + +From: Fabio Pricoco + +commit f88c529ac77b3c21819d2cf1dfcfae1937849743 upstream. + +250 msec timeout is insufficient for some AQ commands. Advice from FW +team was to increase the timeout. Increase to 1 second. + +Fixes: 7ec59eeac804 ("ice: Add support for control queues") +Signed-off-by: Fabio Pricoco +Tested-by: Tony Brelinski +Signed-off-by: Tony Nguyen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/ice/ice_controlq.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/intel/ice/ice_controlq.h ++++ b/drivers/net/ethernet/intel/ice/ice_controlq.h +@@ -31,8 +31,8 @@ enum ice_ctl_q { + ICE_CTL_Q_MAILBOX, + }; + +-/* Control Queue timeout settings - max delay 250ms */ +-#define ICE_CTL_Q_SQ_CMD_TIMEOUT 2500 /* Count 2500 times */ ++/* Control Queue timeout settings - max delay 1s */ ++#define ICE_CTL_Q_SQ_CMD_TIMEOUT 10000 /* Count 10000 times */ + #define ICE_CTL_Q_SQ_CMD_USEC 100 /* Check every 100usec */ + + struct ice_ctl_q_ring { diff --git a/queue-5.4/mac80211-fix-txq-ac-confusion.patch b/queue-5.4/mac80211-fix-txq-ac-confusion.patch new file mode 100644 index 00000000000..948b032969f --- /dev/null +++ b/queue-5.4/mac80211-fix-txq-ac-confusion.patch @@ -0,0 +1,74 @@ +From 1153a74768a9212daadbb50767aa400bc6a0c9b0 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Tue, 23 Mar 2021 21:05:01 +0100 +Subject: mac80211: fix TXQ AC confusion +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Johannes Berg + +commit 1153a74768a9212daadbb50767aa400bc6a0c9b0 upstream. + +Normally, TXQs have + + txq->tid = tid; + txq->ac = ieee80211_ac_from_tid(tid); + +However, the special management TXQ actually has + + txq->tid = IEEE80211_NUM_TIDS; // 16 + txq->ac = IEEE80211_AC_VO; + +This makes sense, but ieee80211_ac_from_tid(16) is the same +as ieee80211_ac_from_tid(0) which is just IEEE80211_AC_BE. + +Now, normally this is fine. However, if the netdev queues +were stopped, then the code in ieee80211_tx_dequeue() will +propagate the stop from the interface (vif->txqs_stopped[]) +if the AC 2 (ieee80211_ac_from_tid(txq->tid)) is marked as +stopped. On wake, however, __ieee80211_wake_txqs() will wake +the TXQ if AC 0 (txq->ac) is woken up. + +If a driver stops all queues with ieee80211_stop_tx_queues() +and then wakes them again with ieee80211_wake_tx_queues(), +the ieee80211_wake_txqs() tasklet will run to resync queue +and TXQ state. If all queues were woken, then what'll happen +is that _ieee80211_wake_txqs() will run in order of HW queues +0-3, typically (and certainly for iwlwifi) corresponding to +ACs 0-3, so it'll call __ieee80211_wake_txqs() for each AC in +order 0-3. + +When __ieee80211_wake_txqs() is called for AC 0 (VO) that'll +wake up the management TXQ (remember its tid is 16), and the +driver's wake_tx_queue() will be called. That tries to get a +frame, which will immediately *stop* the TXQ again, because +now we check against AC 2, and AC 2 hasn't yet been marked as +woken up again in sdata->vif.txqs_stopped[] since we're only +in the __ieee80211_wake_txqs() call for AC 0. + +Thus, the management TXQ will never be started again. + +Fix this by checking txq->ac directly instead of calculating +the AC as ieee80211_ac_from_tid(txq->tid). + +Fixes: adf8ed01e4fd ("mac80211: add an optional TXQ for other PS-buffered frames") +Acked-by: Toke Høiland-Jørgensen +Link: https://lore.kernel.org/r/20210323210500.bf4d50afea4a.I136ffde910486301f8818f5442e3c9bf8670a9c4@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/tx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3582,7 +3582,7 @@ begin: + test_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags)) + goto out; + +- if (vif->txqs_stopped[ieee80211_ac_from_tid(txq->tid)]) { ++ if (vif->txqs_stopped[txq->ac]) { + set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags); + goto out; + } diff --git a/queue-5.4/net-dsa-lantiq_gswip-configure-all-remaining-gswip_mii_cfg-bits.patch b/queue-5.4/net-dsa-lantiq_gswip-configure-all-remaining-gswip_mii_cfg-bits.patch deleted file mode 100644 index fda26aa4f3e..00000000000 --- a/queue-5.4/net-dsa-lantiq_gswip-configure-all-remaining-gswip_mii_cfg-bits.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 4b5923249b8fa427943b50b8f35265176472be38 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Thu, 8 Apr 2021 20:38:28 +0200 -Subject: net: dsa: lantiq_gswip: Configure all remaining GSWIP_MII_CFG bits - -From: Martin Blumenstingl - -commit 4b5923249b8fa427943b50b8f35265176472be38 upstream. - -There are a few more bits in the GSWIP_MII_CFG register for which we -did rely on the boot-loader (or the hardware defaults) to set them up -properly. - -For some external RMII PHYs we need to select the GSWIP_MII_CFG_RMII_CLK -bit and also we should un-set it for non-RMII PHYs. The -GSWIP_MII_CFG_RMII_CLK bit is ignored for other PHY connection modes. - -The GSWIP IP also supports in-band auto-negotiation for RGMII PHYs when -the GSWIP_MII_CFG_RGMII_IBS bit is set. Clear this bit always as there's -no known hardware which uses this (so it is not tested yet). - -Clear the xMII isolation bit when set at initialization time if it was -previously set by the bootloader. Not doing so could lead to no traffic -(neither RX nor TX) on a port with this bit set. - -While here, also add the GSWIP_MII_CFG_RESET bit. We don't need to -manage it because this bit is self-clearning when set. We still add it -here to get a better overview of the GSWIP_MII_CFG register. - -Fixes: 14fceff4771e51 ("net: dsa: Add Lantiq / Intel DSA driver for vrx200") -Cc: stable@vger.kernel.org -Suggested-by: Hauke Mehrtens -Acked-by: Hauke Mehrtens -Signed-off-by: Martin Blumenstingl -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - drivers/net/dsa/lantiq_gswip.c | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - ---- a/drivers/net/dsa/lantiq_gswip.c -+++ b/drivers/net/dsa/lantiq_gswip.c -@@ -93,8 +93,12 @@ - - /* GSWIP MII Registers */ - #define GSWIP_MII_CFGp(p) (0x2 * (p)) -+#define GSWIP_MII_CFG_RESET BIT(15) - #define GSWIP_MII_CFG_EN BIT(14) -+#define GSWIP_MII_CFG_ISOLATE BIT(13) - #define GSWIP_MII_CFG_LDCLKDIS BIT(12) -+#define GSWIP_MII_CFG_RGMII_IBS BIT(8) -+#define GSWIP_MII_CFG_RMII_CLK BIT(7) - #define GSWIP_MII_CFG_MODE_MIIP 0x0 - #define GSWIP_MII_CFG_MODE_MIIM 0x1 - #define GSWIP_MII_CFG_MODE_RMIIP 0x2 -@@ -817,9 +821,11 @@ static int gswip_setup(struct dsa_switch - /* Configure the MDIO Clock 2.5 MHz */ - gswip_mdio_mask(priv, 0xff, 0x09, GSWIP_MDIO_MDC_CFG1); - -- /* Disable the xMII link */ -+ /* Disable the xMII interface and clear it's isolation bit */ - for (i = 0; i < priv->hw_info->max_ports; i++) -- gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, i); -+ gswip_mii_mask_cfg(priv, -+ GSWIP_MII_CFG_EN | GSWIP_MII_CFG_ISOLATE, -+ 0, i); - - /* enable special tag insertion on cpu port */ - gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_STEN, -@@ -1594,6 +1600,9 @@ static void gswip_phylink_mac_config(str - break; - case PHY_INTERFACE_MODE_RMII: - miicfg |= GSWIP_MII_CFG_MODE_RMIIM; -+ -+ /* Configure the RMII clock as output: */ -+ miicfg |= GSWIP_MII_CFG_RMII_CLK; - break; - case PHY_INTERFACE_MODE_RGMII: - case PHY_INTERFACE_MODE_RGMII_ID: -@@ -1606,7 +1615,11 @@ static void gswip_phylink_mac_config(str - "Unsupported interface: %d\n", state->interface); - return; - } -- gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_MODE_MASK, miicfg, port); -+ -+ gswip_mii_mask_cfg(priv, -+ GSWIP_MII_CFG_MODE_MASK | GSWIP_MII_CFG_RMII_CLK | -+ GSWIP_MII_CFG_RGMII_IBS | GSWIP_MII_CFG_LDCLKDIS, -+ miicfg, port); - - switch (state->interface) { - case PHY_INTERFACE_MODE_RGMII_ID: diff --git a/queue-5.4/net-dsa-lantiq_gswip-don-t-use-phy-auto-polling.patch b/queue-5.4/net-dsa-lantiq_gswip-don-t-use-phy-auto-polling.patch deleted file mode 100644 index 06d4c3eecdb..00000000000 --- a/queue-5.4/net-dsa-lantiq_gswip-don-t-use-phy-auto-polling.patch +++ /dev/null @@ -1,317 +0,0 @@ -From 3e9005be87777afc902b9f5497495898202d335d Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Thu, 8 Apr 2021 20:38:27 +0200 -Subject: net: dsa: lantiq_gswip: Don't use PHY auto polling - -From: Martin Blumenstingl - -commit 3e9005be87777afc902b9f5497495898202d335d upstream. - -PHY auto polling on the GSWIP hardware can be used so link changes -(speed, link up/down, etc.) can be detected automatically. Internally -GSWIP reads the PHY's registers for this functionality. Based on this -automatic detection GSWIP can also automatically re-configure it's port -settings. Unfortunately this auto polling (and configuration) mechanism -seems to cause various issues observed by different people on different -devices: -- FritzBox 7360v2: the two Gbit/s ports (connected to the two internal - PHY11G instances) are working fine but the two Fast Ethernet ports - (using an AR8030 RMII PHY) are completely dead (neither RX nor TX are - received). It turns out that the AR8030 PHY sets the BMSR_ESTATEN bit - as well as the ESTATUS_1000_TFULL and ESTATUS_1000_XFULL bits. This - makes the PHY auto polling state machine (rightfully?) think that the - established link speed (when the other side is Gbit/s capable) is - 1Gbit/s. -- None of the Ethernet ports on the Zyxel P-2812HNU-F1 (two are - connected to the internal PHY11G GPHYs while the other three are - external RGMII PHYs) are working. Neither RX nor TX traffic was - observed. It is not clear which part of the PHY auto polling state- - machine caused this. -- FritzBox 7412 (only one LAN port which is connected to one of the - internal GPHYs running in PHY22F / Fast Ethernet mode) was seeing - random disconnects (link down events could be seen). Sometimes all - traffic would stop after such disconnect. It is not clear which part - of the PHY auto polling state-machine cauased this. -- TP-Link TD-W9980 (two ports are connected to the internal GPHYs - running in PHY11G / Gbit/s mode, the other two are external RGMII - PHYs) was affected by similar issues as the FritzBox 7412 just without - the "link down" events - -Switch to software based configuration instead of PHY auto polling (and -letting the GSWIP hardware configure the ports automatically) for the -following link parameters: -- link up/down -- link speed -- full/half duplex -- flow control (RX / TX pause) - -After a big round of manual testing by various people (who helped test -this on OpenWrt) it turns out that this fixes all reported issues. - -Additionally it can be considered more future proof because any -"quirk" which is implemented for a PHY on the driver side can now be -used with the GSWIP hardware as well because Linux is in control of the -link parameters. - -As a nice side-effect this also solves a problem where fixed-links were -not supported previously because we were relying on the PHY auto polling -mechanism, which cannot work for fixed-links as there's no PHY from -where it can read the registers. Configuring the link settings on the -GSWIP ports means that we now use the settings from device-tree also for -ports with fixed-links. - -Fixes: 14fceff4771e51 ("net: dsa: Add Lantiq / Intel DSA driver for vrx200") -Fixes: 3e6fdeb28f4c33 ("net: dsa: lantiq_gswip: Let GSWIP automatically set the xMII clock") -Cc: stable@vger.kernel.org -Acked-by: Hauke Mehrtens -Reviewed-by: Andrew Lunn -Signed-off-by: Martin Blumenstingl -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - drivers/net/dsa/lantiq_gswip.c | 185 +++++++++++++++++++++++++++++++++++------ - 1 file changed, 159 insertions(+), 26 deletions(-) - ---- a/drivers/net/dsa/lantiq_gswip.c -+++ b/drivers/net/dsa/lantiq_gswip.c -@@ -190,6 +190,23 @@ - #define GSWIP_PCE_DEFPVID(p) (0x486 + ((p) * 0xA)) - - #define GSWIP_MAC_FLEN 0x8C5 -+#define GSWIP_MAC_CTRL_0p(p) (0x903 + ((p) * 0xC)) -+#define GSWIP_MAC_CTRL_0_PADEN BIT(8) -+#define GSWIP_MAC_CTRL_0_FCS_EN BIT(7) -+#define GSWIP_MAC_CTRL_0_FCON_MASK 0x0070 -+#define GSWIP_MAC_CTRL_0_FCON_AUTO 0x0000 -+#define GSWIP_MAC_CTRL_0_FCON_RX 0x0010 -+#define GSWIP_MAC_CTRL_0_FCON_TX 0x0020 -+#define GSWIP_MAC_CTRL_0_FCON_RXTX 0x0030 -+#define GSWIP_MAC_CTRL_0_FCON_NONE 0x0040 -+#define GSWIP_MAC_CTRL_0_FDUP_MASK 0x000C -+#define GSWIP_MAC_CTRL_0_FDUP_AUTO 0x0000 -+#define GSWIP_MAC_CTRL_0_FDUP_EN 0x0004 -+#define GSWIP_MAC_CTRL_0_FDUP_DIS 0x000C -+#define GSWIP_MAC_CTRL_0_GMII_MASK 0x0003 -+#define GSWIP_MAC_CTRL_0_GMII_AUTO 0x0000 -+#define GSWIP_MAC_CTRL_0_GMII_MII 0x0001 -+#define GSWIP_MAC_CTRL_0_GMII_RGMII 0x0002 - #define GSWIP_MAC_CTRL_2p(p) (0x905 + ((p) * 0xC)) - #define GSWIP_MAC_CTRL_2_MLEN BIT(3) /* Maximum Untagged Frame Lnegth */ - -@@ -653,16 +670,13 @@ static int gswip_port_enable(struct dsa_ - GSWIP_SDMA_PCTRLp(port)); - - if (!dsa_is_cpu_port(ds, port)) { -- u32 macconf = GSWIP_MDIO_PHY_LINK_AUTO | -- GSWIP_MDIO_PHY_SPEED_AUTO | -- GSWIP_MDIO_PHY_FDUP_AUTO | -- GSWIP_MDIO_PHY_FCONTX_AUTO | -- GSWIP_MDIO_PHY_FCONRX_AUTO | -- (phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK); -- -- gswip_mdio_w(priv, macconf, GSWIP_MDIO_PHYp(port)); -- /* Activate MDIO auto polling */ -- gswip_mdio_mask(priv, 0, BIT(port), GSWIP_MDIO_MDC_CFG0); -+ u32 mdio_phy = 0; -+ -+ if (phydev) -+ mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK; -+ -+ gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy, -+ GSWIP_MDIO_PHYp(port)); - } - - return 0; -@@ -675,14 +689,6 @@ static void gswip_port_disable(struct ds - if (!dsa_is_user_port(ds, port)) - return; - -- if (!dsa_is_cpu_port(ds, port)) { -- gswip_mdio_mask(priv, GSWIP_MDIO_PHY_LINK_DOWN, -- GSWIP_MDIO_PHY_LINK_MASK, -- GSWIP_MDIO_PHYp(port)); -- /* Deactivate MDIO auto polling */ -- gswip_mdio_mask(priv, BIT(port), 0, GSWIP_MDIO_MDC_CFG0); -- } -- - gswip_switch_mask(priv, GSWIP_FDMA_PCTRL_EN, 0, - GSWIP_FDMA_PCTRLp(port)); - gswip_switch_mask(priv, GSWIP_SDMA_PCTRL_EN, 0, -@@ -790,20 +796,31 @@ static int gswip_setup(struct dsa_switch - gswip_switch_w(priv, BIT(cpu_port), GSWIP_PCE_PMAP2); - gswip_switch_w(priv, BIT(cpu_port), GSWIP_PCE_PMAP3); - -- /* disable PHY auto polling */ -+ /* Deactivate MDIO PHY auto polling. Some PHYs as the AR8030 have an -+ * interoperability problem with this auto polling mechanism because -+ * their status registers think that the link is in a different state -+ * than it actually is. For the AR8030 it has the BMSR_ESTATEN bit set -+ * as well as ESTATUS_1000_TFULL and ESTATUS_1000_XFULL. This makes the -+ * auto polling state machine consider the link being negotiated with -+ * 1Gbit/s. Since the PHY itself is a Fast Ethernet RMII PHY this leads -+ * to the switch port being completely dead (RX and TX are both not -+ * working). -+ * Also with various other PHY / port combinations (PHY11G GPHY, PHY22F -+ * GPHY, external RGMII PEF7071/7072) any traffic would stop. Sometimes -+ * it would work fine for a few minutes to hours and then stop, on -+ * other device it would no traffic could be sent or received at all. -+ * Testing shows that when PHY auto polling is disabled these problems -+ * go away. -+ */ - gswip_mdio_w(priv, 0x0, GSWIP_MDIO_MDC_CFG0); -+ - /* Configure the MDIO Clock 2.5 MHz */ - gswip_mdio_mask(priv, 0xff, 0x09, GSWIP_MDIO_MDC_CFG1); - -- for (i = 0; i < priv->hw_info->max_ports; i++) { -- /* Disable the xMII link */ -+ /* Disable the xMII link */ -+ for (i = 0; i < priv->hw_info->max_ports; i++) - gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, i); - -- /* Automatically select the xMII interface clock */ -- gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_RATE_MASK, -- GSWIP_MII_CFG_RATE_AUTO, i); -- } -- - /* enable special tag insertion on cpu port */ - gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_STEN, - GSWIP_FDMA_PCTRLp(cpu_port)); -@@ -1452,6 +1469,112 @@ unsupported: - return; - } - -+static void gswip_port_set_link(struct gswip_priv *priv, int port, bool link) -+{ -+ u32 mdio_phy; -+ -+ if (link) -+ mdio_phy = GSWIP_MDIO_PHY_LINK_UP; -+ else -+ mdio_phy = GSWIP_MDIO_PHY_LINK_DOWN; -+ -+ gswip_mdio_mask(priv, GSWIP_MDIO_PHY_LINK_MASK, mdio_phy, -+ GSWIP_MDIO_PHYp(port)); -+} -+ -+static void gswip_port_set_speed(struct gswip_priv *priv, int port, int speed, -+ phy_interface_t interface) -+{ -+ u32 mdio_phy = 0, mii_cfg = 0, mac_ctrl_0 = 0; -+ -+ switch (speed) { -+ case SPEED_10: -+ mdio_phy = GSWIP_MDIO_PHY_SPEED_M10; -+ -+ if (interface == PHY_INTERFACE_MODE_RMII) -+ mii_cfg = GSWIP_MII_CFG_RATE_M50; -+ else -+ mii_cfg = GSWIP_MII_CFG_RATE_M2P5; -+ -+ mac_ctrl_0 = GSWIP_MAC_CTRL_0_GMII_MII; -+ break; -+ -+ case SPEED_100: -+ mdio_phy = GSWIP_MDIO_PHY_SPEED_M100; -+ -+ if (interface == PHY_INTERFACE_MODE_RMII) -+ mii_cfg = GSWIP_MII_CFG_RATE_M50; -+ else -+ mii_cfg = GSWIP_MII_CFG_RATE_M25; -+ -+ mac_ctrl_0 = GSWIP_MAC_CTRL_0_GMII_MII; -+ break; -+ -+ case SPEED_1000: -+ mdio_phy = GSWIP_MDIO_PHY_SPEED_G1; -+ -+ mii_cfg = GSWIP_MII_CFG_RATE_M125; -+ -+ mac_ctrl_0 = GSWIP_MAC_CTRL_0_GMII_RGMII; -+ break; -+ } -+ -+ gswip_mdio_mask(priv, GSWIP_MDIO_PHY_SPEED_MASK, mdio_phy, -+ GSWIP_MDIO_PHYp(port)); -+ gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_RATE_MASK, mii_cfg, port); -+ gswip_switch_mask(priv, GSWIP_MAC_CTRL_0_GMII_MASK, mac_ctrl_0, -+ GSWIP_MAC_CTRL_0p(port)); -+} -+ -+static void gswip_port_set_duplex(struct gswip_priv *priv, int port, int duplex) -+{ -+ u32 mac_ctrl_0, mdio_phy; -+ -+ if (duplex == DUPLEX_FULL) { -+ mac_ctrl_0 = GSWIP_MAC_CTRL_0_FDUP_EN; -+ mdio_phy = GSWIP_MDIO_PHY_FDUP_EN; -+ } else { -+ mac_ctrl_0 = GSWIP_MAC_CTRL_0_FDUP_DIS; -+ mdio_phy = GSWIP_MDIO_PHY_FDUP_DIS; -+ } -+ -+ gswip_switch_mask(priv, GSWIP_MAC_CTRL_0_FDUP_MASK, mac_ctrl_0, -+ GSWIP_MAC_CTRL_0p(port)); -+ gswip_mdio_mask(priv, GSWIP_MDIO_PHY_FDUP_MASK, mdio_phy, -+ GSWIP_MDIO_PHYp(port)); -+} -+ -+static void gswip_port_set_pause(struct gswip_priv *priv, int port, -+ bool tx_pause, bool rx_pause) -+{ -+ u32 mac_ctrl_0, mdio_phy; -+ -+ if (tx_pause && rx_pause) { -+ mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_RXTX; -+ mdio_phy = GSWIP_MDIO_PHY_FCONTX_EN | -+ GSWIP_MDIO_PHY_FCONRX_EN; -+ } else if (tx_pause) { -+ mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_TX; -+ mdio_phy = GSWIP_MDIO_PHY_FCONTX_EN | -+ GSWIP_MDIO_PHY_FCONRX_DIS; -+ } else if (rx_pause) { -+ mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_RX; -+ mdio_phy = GSWIP_MDIO_PHY_FCONTX_DIS | -+ GSWIP_MDIO_PHY_FCONRX_EN; -+ } else { -+ mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_NONE; -+ mdio_phy = GSWIP_MDIO_PHY_FCONTX_DIS | -+ GSWIP_MDIO_PHY_FCONRX_DIS; -+ } -+ -+ gswip_switch_mask(priv, GSWIP_MAC_CTRL_0_FCON_MASK, -+ mac_ctrl_0, GSWIP_MAC_CTRL_0p(port)); -+ gswip_mdio_mask(priv, -+ GSWIP_MDIO_PHY_FCONTX_MASK | -+ GSWIP_MDIO_PHY_FCONRX_MASK, -+ mdio_phy, GSWIP_MDIO_PHYp(port)); -+} -+ - static void gswip_phylink_mac_config(struct dsa_switch *ds, int port, - unsigned int mode, - const struct phylink_link_state *state) -@@ -1508,6 +1631,9 @@ static void gswip_phylink_mac_link_down( - struct gswip_priv *priv = ds->priv; - - gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, port); -+ -+ if (!dsa_is_cpu_port(ds, port)) -+ gswip_port_set_link(priv, port, false); - } - - static void gswip_phylink_mac_link_up(struct dsa_switch *ds, int port, -@@ -1517,6 +1643,13 @@ static void gswip_phylink_mac_link_up(st - { - struct gswip_priv *priv = ds->priv; - -+ if (!dsa_is_cpu_port(ds, port)) { -+ gswip_port_set_link(priv, port, true); -+ gswip_port_set_speed(priv, port, speed, interface); -+ gswip_port_set_duplex(priv, port, duplex); -+ gswip_port_set_pause(priv, port, tx_pause, rx_pause); -+ } -+ - gswip_mii_mask_cfg(priv, 0, GSWIP_MII_CFG_EN, port); - } - diff --git a/queue-5.4/net-ensure-mac-header-is-set-in-virtio_net_hdr_to_skb.patch b/queue-5.4/net-ensure-mac-header-is-set-in-virtio_net_hdr_to_skb.patch new file mode 100644 index 00000000000..001b98e2fe8 --- /dev/null +++ b/queue-5.4/net-ensure-mac-header-is-set-in-virtio_net_hdr_to_skb.patch @@ -0,0 +1,77 @@ +From 61431a5907fc36d0738e9a547c7e1556349a03e9 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 30 Mar 2021 16:43:43 -0700 +Subject: net: ensure mac header is set in virtio_net_hdr_to_skb() + +From: Eric Dumazet + +commit 61431a5907fc36d0738e9a547c7e1556349a03e9 upstream. + +Commit 924a9bc362a5 ("net: check if protocol extracted by virtio_net_hdr_set_proto is correct") +added a call to dev_parse_header_protocol() but mac_header is not yet set. + +This means that eth_hdr() reads complete garbage, and syzbot complained about it [1] + +This patch resets mac_header earlier, to get more coverage about this change. + +Audit of virtio_net_hdr_to_skb() callers shows that this change should be safe. + +[1] + +BUG: KASAN: use-after-free in eth_header_parse_protocol+0xdc/0xe0 net/ethernet/eth.c:282 +Read of size 2 at addr ffff888017a6200b by task syz-executor313/8409 + +CPU: 1 PID: 8409 Comm: syz-executor313 Not tainted 5.12.0-rc2-syzkaller #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:79 [inline] + dump_stack+0x141/0x1d7 lib/dump_stack.c:120 + print_address_description.constprop.0.cold+0x5b/0x2f8 mm/kasan/report.c:232 + __kasan_report mm/kasan/report.c:399 [inline] + kasan_report.cold+0x7c/0xd8 mm/kasan/report.c:416 + eth_header_parse_protocol+0xdc/0xe0 net/ethernet/eth.c:282 + dev_parse_header_protocol include/linux/netdevice.h:3177 [inline] + virtio_net_hdr_to_skb.constprop.0+0x99d/0xcd0 include/linux/virtio_net.h:83 + packet_snd net/packet/af_packet.c:2994 [inline] + packet_sendmsg+0x2325/0x52b0 net/packet/af_packet.c:3031 + sock_sendmsg_nosec net/socket.c:654 [inline] + sock_sendmsg+0xcf/0x120 net/socket.c:674 + sock_no_sendpage+0xf3/0x130 net/core/sock.c:2860 + kernel_sendpage.part.0+0x1ab/0x350 net/socket.c:3631 + kernel_sendpage net/socket.c:3628 [inline] + sock_sendpage+0xe5/0x140 net/socket.c:947 + pipe_to_sendpage+0x2ad/0x380 fs/splice.c:364 + splice_from_pipe_feed fs/splice.c:418 [inline] + __splice_from_pipe+0x43e/0x8a0 fs/splice.c:562 + splice_from_pipe fs/splice.c:597 [inline] + generic_splice_sendpage+0xd4/0x140 fs/splice.c:746 + do_splice_from fs/splice.c:767 [inline] + do_splice+0xb7e/0x1940 fs/splice.c:1079 + __do_splice+0x134/0x250 fs/splice.c:1144 + __do_sys_splice fs/splice.c:1350 [inline] + __se_sys_splice fs/splice.c:1332 [inline] + __x64_sys_splice+0x198/0x250 fs/splice.c:1332 + do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 + +Fixes: 924a9bc362a5 ("net: check if protocol extracted by virtio_net_hdr_set_proto is correct") +Signed-off-by: Eric Dumazet +Cc: Balazs Nemeth +Cc: Willem de Bruijn +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/virtio_net.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/include/linux/virtio_net.h ++++ b/include/linux/virtio_net.h +@@ -62,6 +62,8 @@ static inline int virtio_net_hdr_to_skb( + return -EINVAL; + } + ++ skb_reset_mac_header(skb); ++ + if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { + u16 start = __virtio16_to_cpu(little_endian, hdr->csum_start); + u16 off = __virtio16_to_cpu(little_endian, hdr->csum_offset); diff --git a/queue-5.4/net-hso-fix-null-ptr-deref-during-tty-device-unregistration.patch b/queue-5.4/net-hso-fix-null-ptr-deref-during-tty-device-unregistration.patch new file mode 100644 index 00000000000..5ec6910e371 --- /dev/null +++ b/queue-5.4/net-hso-fix-null-ptr-deref-during-tty-device-unregistration.patch @@ -0,0 +1,143 @@ +From 8a12f8836145ffe37e9c8733dce18c22fb668b66 Mon Sep 17 00:00:00 2001 +From: Anirudh Rayabharam +Date: Wed, 7 Apr 2021 22:57:22 +0530 +Subject: net: hso: fix null-ptr-deref during tty device unregistration + +From: Anirudh Rayabharam + +commit 8a12f8836145ffe37e9c8733dce18c22fb668b66 upstream. + +Multiple ttys try to claim the same the minor number causing a double +unregistration of the same device. The first unregistration succeeds +but the next one results in a null-ptr-deref. + +The get_free_serial_index() function returns an available minor number +but doesn't assign it immediately. The assignment is done by the caller +later. But before this assignment, calls to get_free_serial_index() +would return the same minor number. + +Fix this by modifying get_free_serial_index to assign the minor number +immediately after one is found to be and rename it to obtain_minor() +to better reflect what it does. Similary, rename set_serial_by_index() +to release_minor() and modify it to free up the minor number of the +given hso_serial. Every obtain_minor() should have corresponding +release_minor() call. + +Fixes: 72dc1c096c705 ("HSO: add option hso driver") +Reported-by: syzbot+c49fe6089f295a05e6f8@syzkaller.appspotmail.com +Tested-by: syzbot+c49fe6089f295a05e6f8@syzkaller.appspotmail.com +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Anirudh Rayabharam +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/hso.c | 33 ++++++++++++--------------------- + 1 file changed, 12 insertions(+), 21 deletions(-) + +--- a/drivers/net/usb/hso.c ++++ b/drivers/net/usb/hso.c +@@ -611,7 +611,7 @@ static struct hso_serial *get_serial_by_ + return serial; + } + +-static int get_free_serial_index(void) ++static int obtain_minor(struct hso_serial *serial) + { + int index; + unsigned long flags; +@@ -619,8 +619,10 @@ static int get_free_serial_index(void) + spin_lock_irqsave(&serial_table_lock, flags); + for (index = 0; index < HSO_SERIAL_TTY_MINORS; index++) { + if (serial_table[index] == NULL) { ++ serial_table[index] = serial->parent; ++ serial->minor = index; + spin_unlock_irqrestore(&serial_table_lock, flags); +- return index; ++ return 0; + } + } + spin_unlock_irqrestore(&serial_table_lock, flags); +@@ -629,15 +631,12 @@ static int get_free_serial_index(void) + return -1; + } + +-static void set_serial_by_index(unsigned index, struct hso_serial *serial) ++static void release_minor(struct hso_serial *serial) + { + unsigned long flags; + + spin_lock_irqsave(&serial_table_lock, flags); +- if (serial) +- serial_table[index] = serial->parent; +- else +- serial_table[index] = NULL; ++ serial_table[serial->minor] = NULL; + spin_unlock_irqrestore(&serial_table_lock, flags); + } + +@@ -2230,6 +2229,7 @@ static int hso_stop_serial_device(struct + static void hso_serial_tty_unregister(struct hso_serial *serial) + { + tty_unregister_device(tty_drv, serial->minor); ++ release_minor(serial); + } + + static void hso_serial_common_free(struct hso_serial *serial) +@@ -2253,24 +2253,22 @@ static void hso_serial_common_free(struc + static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, + int rx_size, int tx_size) + { +- int minor; + int i; + + tty_port_init(&serial->port); + +- minor = get_free_serial_index(); +- if (minor < 0) ++ if (obtain_minor(serial)) + goto exit2; + + /* register our minor number */ + serial->parent->dev = tty_port_register_device_attr(&serial->port, +- tty_drv, minor, &serial->parent->interface->dev, ++ tty_drv, serial->minor, &serial->parent->interface->dev, + serial->parent, hso_serial_dev_groups); +- if (IS_ERR(serial->parent->dev)) ++ if (IS_ERR(serial->parent->dev)) { ++ release_minor(serial); + goto exit2; ++ } + +- /* fill in specific data for later use */ +- serial->minor = minor; + serial->magic = HSO_SERIAL_MAGIC; + spin_lock_init(&serial->serial_lock); + serial->num_rx_urbs = num_urbs; +@@ -2668,9 +2666,6 @@ static struct hso_device *hso_create_bul + + serial->write_data = hso_std_serial_write_data; + +- /* and record this serial */ +- set_serial_by_index(serial->minor, serial); +- + /* setup the proc dirs and files if needed */ + hso_log_port(hso_dev); + +@@ -2727,9 +2722,6 @@ struct hso_device *hso_create_mux_serial + serial->shared_int->ref_count++; + mutex_unlock(&serial->shared_int->shared_int_lock); + +- /* and record this serial */ +- set_serial_by_index(serial->minor, serial); +- + /* setup the proc dirs and files if needed */ + hso_log_port(hso_dev); + +@@ -3114,7 +3106,6 @@ static void hso_free_interface(struct us + cancel_work_sync(&serial_table[i]->async_get_intf); + hso_serial_tty_unregister(serial); + kref_put(&serial_table[i]->ref, hso_serial_ref_free); +- set_serial_by_index(i, NULL); + } + } + diff --git a/queue-5.4/net-hsr-reset-mac-header-for-tx-path.patch b/queue-5.4/net-hsr-reset-mac-header-for-tx-path.patch new file mode 100644 index 00000000000..9fc7f06e97b --- /dev/null +++ b/queue-5.4/net-hsr-reset-mac-header-for-tx-path.patch @@ -0,0 +1,66 @@ +From 9d6803921a16f4d768dc41a75375629828f4d91e Mon Sep 17 00:00:00 2001 +From: Kurt Kanzenbach +Date: Tue, 6 Apr 2021 09:35:09 +0200 +Subject: net: hsr: Reset MAC header for Tx path + +From: Kurt Kanzenbach + +commit 9d6803921a16f4d768dc41a75375629828f4d91e upstream. + +Reset MAC header in HSR Tx path. This is needed, because direct packet +transmission, e.g. by specifying PACKET_QDISC_BYPASS does not reset the MAC +header. + +This has been observed using the following setup: + +|$ ip link add name hsr0 type hsr slave1 lan0 slave2 lan1 supervision 45 version 1 +|$ ifconfig hsr0 up +|$ ./test hsr0 + +The test binary is using mmap'ed sockets and is specifying the +PACKET_QDISC_BYPASS socket option. + +This patch resolves the following warning on a non-patched kernel: + +|[ 112.725394] ------------[ cut here ]------------ +|[ 112.731418] WARNING: CPU: 1 PID: 257 at net/hsr/hsr_forward.c:560 hsr_forward_skb+0x484/0x568 +|[ 112.739962] net/hsr/hsr_forward.c:560: Malformed frame (port_src hsr0) + +The warning can be safely removed, because the other call sites of +hsr_forward_skb() make sure that the skb is prepared correctly. + +Fixes: d346a3fae3ff ("packet: introduce PACKET_QDISC_BYPASS socket option") +Signed-off-by: Kurt Kanzenbach +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/hsr/hsr_device.c | 1 + + net/hsr/hsr_forward.c | 6 ------ + 2 files changed, 1 insertion(+), 6 deletions(-) + +--- a/net/hsr/hsr_device.c ++++ b/net/hsr/hsr_device.c +@@ -229,6 +229,7 @@ static int hsr_dev_xmit(struct sk_buff * + master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); + if (master) { + skb->dev = master->dev; ++ skb_reset_mac_header(skb); + hsr_forward_skb(skb, master); + } else { + atomic_long_inc(&dev->tx_dropped); +--- a/net/hsr/hsr_forward.c ++++ b/net/hsr/hsr_forward.c +@@ -349,12 +349,6 @@ void hsr_forward_skb(struct sk_buff *skb + { + struct hsr_frame_info frame; + +- if (skb_mac_header(skb) != skb->data) { +- WARN_ONCE(1, "%s:%d: Malformed frame (port_src %s)\n", +- __FILE__, __LINE__, port->dev->name); +- goto out_drop; +- } +- + if (hsr_fill_frame_info(&frame, skb, port) < 0) + goto out_drop; + hsr_register_frame_in(frame.node_src, port, frame.sequence_nr); diff --git a/queue-5.4/net-ipv6-bugfix-raw-sctp-switch-to-ipv6_can_nonlocal_bind.patch b/queue-5.4/net-ipv6-bugfix-raw-sctp-switch-to-ipv6_can_nonlocal_bind.patch new file mode 100644 index 00000000000..83a01a9ef56 --- /dev/null +++ b/queue-5.4/net-ipv6-bugfix-raw-sctp-switch-to-ipv6_can_nonlocal_bind.patch @@ -0,0 +1,85 @@ +From 630e4576f83accf90366686f39808d665d8dbecc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= +Date: Mon, 5 Apr 2021 00:06:52 -0700 +Subject: net-ipv6: bugfix - raw & sctp - switch to ipv6_can_nonlocal_bind() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Maciej Żenczykowski + +commit 630e4576f83accf90366686f39808d665d8dbecc upstream. + +Found by virtue of ipv6 raw sockets not honouring the per-socket +IP{,V6}_FREEBIND setting. + +Based on hits found via: + git grep '[.]ip_nonlocal_bind' +We fix both raw ipv6 sockets to honour IP{,V6}_FREEBIND and IP{,V6}_TRANSPARENT, +and we fix sctp sockets to honour IP{,V6}_TRANSPARENT (they already honoured +FREEBIND), and not just the ipv6 'ip_nonlocal_bind' sysctl. + +The helper is defined as: + static inline bool ipv6_can_nonlocal_bind(struct net *net, struct inet_sock *inet) { + return net->ipv6.sysctl.ip_nonlocal_bind || inet->freebind || inet->transparent; + } +so this change only widens the accepted opt-outs and is thus a clean bugfix. + +I'm not entirely sure what 'fixes' tag to add, since this is AFAICT an ancient bug, +but IMHO this should be applied to stable kernels as far back as possible. +As such I'm adding a 'fixes' tag with the commit that originally added the helper, +which happened in 4.19. Backporting to older LTS kernels (at least 4.9 and 4.14) +would presumably require open-coding it or backporting the helper as well. + +Other possibly relevant commits: + v4.18-rc6-1502-g83ba4645152d net: add helpers checking if socket can be bound to nonlocal address + v4.18-rc6-1431-gd0c1f01138c4 net/ipv6: allow any source address for sendmsg pktinfo with ip_nonlocal_bind + v4.14-rc5-271-gb71d21c274ef sctp: full support for ipv6 ip_nonlocal_bind & IP_FREEBIND + v4.7-rc7-1883-g9b9742022888 sctp: support ipv6 nonlocal bind + v4.1-12247-g35a256fee52c ipv6: Nonlocal bind + +Cc: Lorenzo Colitti +Fixes: 83ba4645152d ("net: add helpers checking if socket can be bound to nonlocal address") +Signed-off-by: Maciej Żenczykowski +Reviewed-By: Lorenzo Colitti +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/raw.c | 2 +- + net/sctp/ipv6.c | 7 +++---- + 2 files changed, 4 insertions(+), 5 deletions(-) + +--- a/net/ipv6/raw.c ++++ b/net/ipv6/raw.c +@@ -298,7 +298,7 @@ static int rawv6_bind(struct sock *sk, s + */ + v4addr = LOOPBACK4_IPV6; + if (!(addr_type & IPV6_ADDR_MULTICAST) && +- !sock_net(sk)->ipv6.sysctl.ip_nonlocal_bind) { ++ !ipv6_can_nonlocal_bind(sock_net(sk), inet)) { + err = -EADDRNOTAVAIL; + if (!ipv6_chk_addr(sock_net(sk), &addr->sin6_addr, + dev, 0)) { +--- a/net/sctp/ipv6.c ++++ b/net/sctp/ipv6.c +@@ -643,8 +643,8 @@ static int sctp_v6_available(union sctp_ + if (!(type & IPV6_ADDR_UNICAST)) + return 0; + +- return sp->inet.freebind || net->ipv6.sysctl.ip_nonlocal_bind || +- ipv6_chk_addr(net, in6, NULL, 0); ++ return ipv6_can_nonlocal_bind(net, &sp->inet) || ++ ipv6_chk_addr(net, in6, NULL, 0); + } + + /* This function checks if the address is a valid address to be used for +@@ -933,8 +933,7 @@ static int sctp_inet6_bind_verify(struct + net = sock_net(&opt->inet.sk); + rcu_read_lock(); + dev = dev_get_by_index_rcu(net, addr->v6.sin6_scope_id); +- if (!dev || !(opt->inet.freebind || +- net->ipv6.sysctl.ip_nonlocal_bind || ++ if (!dev || !(ipv6_can_nonlocal_bind(net, &opt->inet) || + ipv6_chk_addr(net, &addr->v6.sin6_addr, + dev, 0))) { + rcu_read_unlock(); diff --git a/queue-5.4/net-let-skb_orphan_partial-wake-up-waiters.patch b/queue-5.4/net-let-skb_orphan_partial-wake-up-waiters.patch new file mode 100644 index 00000000000..89a70493c45 --- /dev/null +++ b/queue-5.4/net-let-skb_orphan_partial-wake-up-waiters.patch @@ -0,0 +1,78 @@ +From 9adc89af724f12a03b47099cd943ed54e877cd59 Mon Sep 17 00:00:00 2001 +From: Paolo Abeni +Date: Tue, 30 Mar 2021 18:43:54 +0200 +Subject: net: let skb_orphan_partial wake-up waiters. + +From: Paolo Abeni + +commit 9adc89af724f12a03b47099cd943ed54e877cd59 upstream. + +Currently the mentioned helper can end-up freeing the socket wmem +without waking-up any processes waiting for more write memory. + +If the partially orphaned skb is attached to an UDP (or raw) socket, +the lack of wake-up can hang the user-space. + +Even for TCP sockets not calling the sk destructor could have bad +effects on TSQ. + +Address the issue using skb_orphan to release the sk wmem before +setting the new sock_efree destructor. Additionally bundle the +whole ownership update in a new helper, so that later other +potential users could avoid duplicate code. + +v1 -> v2: + - use skb_orphan() instead of sort of open coding it (Eric) + - provide an helper for the ownership change (Eric) + +Fixes: f6ba8d33cfbb ("netem: fix skb_orphan_partial()") +Suggested-by: Eric Dumazet +Signed-off-by: Paolo Abeni +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/sock.h | 9 +++++++++ + net/core/sock.c | 12 +++--------- + 2 files changed, 12 insertions(+), 9 deletions(-) + +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -2150,6 +2150,15 @@ static inline void skb_set_owner_r(struc + sk_mem_charge(sk, skb->truesize); + } + ++static inline void skb_set_owner_sk_safe(struct sk_buff *skb, struct sock *sk) ++{ ++ if (sk && refcount_inc_not_zero(&sk->sk_refcnt)) { ++ skb_orphan(skb); ++ skb->destructor = sock_efree; ++ skb->sk = sk; ++ } ++} ++ + void sk_reset_timer(struct sock *sk, struct timer_list *timer, + unsigned long expires); + +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -2026,16 +2026,10 @@ void skb_orphan_partial(struct sk_buff * + if (skb_is_tcp_pure_ack(skb)) + return; + +- if (can_skb_orphan_partial(skb)) { +- struct sock *sk = skb->sk; +- +- if (refcount_inc_not_zero(&sk->sk_refcnt)) { +- WARN_ON(refcount_sub_and_test(skb->truesize, &sk->sk_wmem_alloc)); +- skb->destructor = sock_efree; +- } +- } else { ++ if (can_skb_orphan_partial(skb)) ++ skb_set_owner_sk_safe(skb, skb->sk); ++ else + skb_orphan(skb); +- } + } + EXPORT_SYMBOL(skb_orphan_partial); + diff --git a/queue-5.4/net-sched-fix-action-overwrite-reference-counting.patch b/queue-5.4/net-sched-fix-action-overwrite-reference-counting.patch new file mode 100644 index 00000000000..0fa95b388c7 --- /dev/null +++ b/queue-5.4/net-sched-fix-action-overwrite-reference-counting.patch @@ -0,0 +1,171 @@ +From 87c750e8c38bce706eb32e4d8f1e3402f2cebbd4 Mon Sep 17 00:00:00 2001 +From: Vlad Buslov +Date: Wed, 7 Apr 2021 18:36:03 +0300 +Subject: net: sched: fix action overwrite reference counting + +From: Vlad Buslov + +commit 87c750e8c38bce706eb32e4d8f1e3402f2cebbd4 upstream. + +Action init code increments reference counter when it changes an action. +This is the desired behavior for cls API which needs to obtain action +reference for every classifier that points to action. However, act API just +needs to change the action and releases the reference before returning. +This sequence breaks when the requested action doesn't exist, which causes +act API init code to create new action with specified index, but action is +still released before returning and is deleted (unless it was referenced +concurrently by cls API). + +Reproduction: + +$ sudo tc actions ls action gact +$ sudo tc actions change action gact drop index 1 +$ sudo tc actions ls action gact + +Extend tcf_action_init() to accept 'init_res' array and initialize it with +action->ops->init() result. In tcf_action_add() remove pointers to created +actions from actions array before passing it to tcf_action_put_many(). + +Fixes: cae422f379f3 ("net: sched: use reference counting action init") +Reported-by: Kumar Kartikeya Dwivedi +Signed-off-by: Vlad Buslov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/act_api.h | 5 +++-- + net/sched/act_api.c | 22 +++++++++++++++------- + net/sched/cls_api.c | 9 +++++---- + 3 files changed, 23 insertions(+), 13 deletions(-) + +diff --git a/include/net/act_api.h b/include/net/act_api.h +index 2bf3092ae7ec..312f0f6554a0 100644 +--- a/include/net/act_api.h ++++ b/include/net/act_api.h +@@ -185,7 +185,7 @@ int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions, + int nr_actions, struct tcf_result *res); + int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla, + struct nlattr *est, char *name, int ovr, int bind, +- struct tc_action *actions[], size_t *attr_size, ++ struct tc_action *actions[], int init_res[], size_t *attr_size, + bool rtnl_held, struct netlink_ext_ack *extack); + struct tc_action_ops *tc_action_load_ops(char *name, struct nlattr *nla, + bool rtnl_held, +@@ -193,7 +193,8 @@ struct tc_action_ops *tc_action_load_ops(char *name, struct nlattr *nla, + struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp, + struct nlattr *nla, struct nlattr *est, + char *name, int ovr, int bind, +- struct tc_action_ops *ops, bool rtnl_held, ++ struct tc_action_ops *a_o, int *init_res, ++ bool rtnl_held, + struct netlink_ext_ack *extack); + int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[], int bind, + int ref, bool terse); +diff --git a/net/sched/act_api.c b/net/sched/act_api.c +index b919826939e0..50854cfbfcdb 100644 +--- a/net/sched/act_api.c ++++ b/net/sched/act_api.c +@@ -992,7 +992,8 @@ struct tc_action_ops *tc_action_load_ops(char *name, struct nlattr *nla, + struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp, + struct nlattr *nla, struct nlattr *est, + char *name, int ovr, int bind, +- struct tc_action_ops *a_o, bool rtnl_held, ++ struct tc_action_ops *a_o, int *init_res, ++ bool rtnl_held, + struct netlink_ext_ack *extack) + { + struct nla_bitfield32 flags = { 0, 0 }; +@@ -1028,6 +1029,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp, + } + if (err < 0) + goto err_out; ++ *init_res = err; + + if (!name && tb[TCA_ACT_COOKIE]) + tcf_set_action_cookie(&a->act_cookie, cookie); +@@ -1056,7 +1058,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp, + + int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla, + struct nlattr *est, char *name, int ovr, int bind, +- struct tc_action *actions[], size_t *attr_size, ++ struct tc_action *actions[], int init_res[], size_t *attr_size, + bool rtnl_held, struct netlink_ext_ack *extack) + { + struct tc_action_ops *ops[TCA_ACT_MAX_PRIO] = {}; +@@ -1084,7 +1086,8 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla, + + for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { + act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind, +- ops[i - 1], rtnl_held, extack); ++ ops[i - 1], &init_res[i - 1], rtnl_held, ++ extack); + if (IS_ERR(act)) { + err = PTR_ERR(act); + goto err; +@@ -1497,12 +1500,13 @@ static int tcf_action_add(struct net *net, struct nlattr *nla, + struct netlink_ext_ack *extack) + { + size_t attr_size = 0; +- int loop, ret; ++ int loop, ret, i; + struct tc_action *actions[TCA_ACT_MAX_PRIO] = {}; ++ int init_res[TCA_ACT_MAX_PRIO] = {}; + + for (loop = 0; loop < 10; loop++) { + ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0, +- actions, &attr_size, true, extack); ++ actions, init_res, &attr_size, true, extack); + if (ret != -EAGAIN) + break; + } +@@ -1510,8 +1514,12 @@ static int tcf_action_add(struct net *net, struct nlattr *nla, + if (ret < 0) + return ret; + ret = tcf_add_notify(net, n, actions, portid, attr_size, extack); +- if (ovr) +- tcf_action_put_many(actions); ++ ++ /* only put existing actions */ ++ for (i = 0; i < TCA_ACT_MAX_PRIO; i++) ++ if (init_res[i] == ACT_P_CREATED) ++ actions[i] = NULL; ++ tcf_action_put_many(actions); + + return ret; + } +diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c +index 9332ec6863e8..9ecb91ebf094 100644 +--- a/net/sched/cls_api.c ++++ b/net/sched/cls_api.c +@@ -3040,6 +3040,7 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, + { + #ifdef CONFIG_NET_CLS_ACT + { ++ int init_res[TCA_ACT_MAX_PRIO] = {}; + struct tc_action *act; + size_t attr_size = 0; + +@@ -3051,8 +3052,8 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, + return PTR_ERR(a_o); + act = tcf_action_init_1(net, tp, tb[exts->police], + rate_tlv, "police", ovr, +- TCA_ACT_BIND, a_o, rtnl_held, +- extack); ++ TCA_ACT_BIND, a_o, init_res, ++ rtnl_held, extack); + if (IS_ERR(act)) { + module_put(a_o->owner); + return PTR_ERR(act); +@@ -3067,8 +3068,8 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, + + err = tcf_action_init(net, tp, tb[exts->action], + rate_tlv, NULL, ovr, TCA_ACT_BIND, +- exts->actions, &attr_size, +- rtnl_held, extack); ++ exts->actions, init_res, ++ &attr_size, rtnl_held, extack); + if (err < 0) + return err; + exts->nr_actions = err; +-- +2.31.1 + diff --git a/queue-5.4/net-sched-sch_teql-fix-null-pointer-dereference.patch b/queue-5.4/net-sched-sch_teql-fix-null-pointer-dereference.patch new file mode 100644 index 00000000000..eeead2348b2 --- /dev/null +++ b/queue-5.4/net-sched-sch_teql-fix-null-pointer-dereference.patch @@ -0,0 +1,92 @@ +From 1ffbc7ea91606e4abd10eb60de5367f1c86daf5e Mon Sep 17 00:00:00 2001 +From: Pavel Tikhomirov +Date: Thu, 8 Apr 2021 18:14:31 +0300 +Subject: net: sched: sch_teql: fix null-pointer dereference + +From: Pavel Tikhomirov + +commit 1ffbc7ea91606e4abd10eb60de5367f1c86daf5e upstream. + +Reproduce: + + modprobe sch_teql + tc qdisc add dev teql0 root teql0 + +This leads to (for instance in Centos 7 VM) OOPS: + +[ 532.366633] BUG: unable to handle kernel NULL pointer dereference at 00000000000000a8 +[ 532.366733] IP: [] teql_destroy+0x18/0x100 [sch_teql] +[ 532.366825] PGD 80000001376d5067 PUD 137e37067 PMD 0 +[ 532.366906] Oops: 0000 [#1] SMP +[ 532.366987] Modules linked in: sch_teql ... +[ 532.367945] CPU: 1 PID: 3026 Comm: tc Kdump: loaded Tainted: G ------------ T 3.10.0-1062.7.1.el7.x86_64 #1 +[ 532.368041] Hardware name: Virtuozzo KVM, BIOS 1.11.0-2.vz7.2 04/01/2014 +[ 532.368125] task: ffff8b7d37d31070 ti: ffff8b7c9fdbc000 task.ti: ffff8b7c9fdbc000 +[ 532.368224] RIP: 0010:[] [] teql_destroy+0x18/0x100 [sch_teql] +[ 532.368320] RSP: 0018:ffff8b7c9fdbf8e0 EFLAGS: 00010286 +[ 532.368394] RAX: ffffffffc0612490 RBX: ffff8b7cb1565e00 RCX: ffff8b7d35ba2000 +[ 532.368476] RDX: ffff8b7d35ba2000 RSI: 0000000000000000 RDI: ffff8b7cb1565e00 +[ 532.368557] RBP: ffff8b7c9fdbf8f8 R08: ffff8b7d3fd1f140 R09: ffff8b7d3b001600 +[ 532.368638] R10: ffff8b7d3b001600 R11: ffffffff84c7d65b R12: 00000000ffffffd8 +[ 532.368719] R13: 0000000000008000 R14: ffff8b7d35ba2000 R15: ffff8b7c9fdbf9a8 +[ 532.368800] FS: 00007f6a4e872740(0000) GS:ffff8b7d3fd00000(0000) knlGS:0000000000000000 +[ 532.368885] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 532.368961] CR2: 00000000000000a8 CR3: 00000001396ee000 CR4: 00000000000206e0 +[ 532.369046] Call Trace: +[ 532.369159] [] qdisc_create+0x36e/0x450 +[ 532.369268] [] ? ns_capable+0x29/0x50 +[ 532.369366] [] ? nla_parse+0x32/0x120 +[ 532.369442] [] tc_modify_qdisc+0x13c/0x610 +[ 532.371508] [] rtnetlink_rcv_msg+0xa7/0x260 +[ 532.372668] [] ? sock_has_perm+0x75/0x90 +[ 532.373790] [] ? rtnl_newlink+0x890/0x890 +[ 532.374914] [] netlink_rcv_skb+0xab/0xc0 +[ 532.376055] [] rtnetlink_rcv+0x28/0x30 +[ 532.377204] [] netlink_unicast+0x170/0x210 +[ 532.378333] [] netlink_sendmsg+0x308/0x420 +[ 532.379465] [] sock_sendmsg+0xb6/0xf0 +[ 532.380710] [] ? __xfs_filemap_fault+0x8e/0x1d0 [xfs] +[ 532.381868] [] ? xfs_filemap_fault+0x2c/0x30 [xfs] +[ 532.383037] [] ? __do_fault.isra.61+0x8a/0x100 +[ 532.384144] [] ___sys_sendmsg+0x3e9/0x400 +[ 532.385268] [] ? handle_mm_fault+0x39d/0x9b0 +[ 532.386387] [] ? __do_page_fault+0x238/0x500 +[ 532.387472] [] __sys_sendmsg+0x51/0x90 +[ 532.388560] [] SyS_sendmsg+0x12/0x20 +[ 532.389636] [] system_call_fastpath+0x25/0x2a +[ 532.390704] [] ? system_call_after_swapgs+0xae/0x146 +[ 532.391753] Code: 00 00 00 00 00 00 5b 5d c3 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 48 89 e5 41 55 41 54 53 48 8b b7 48 01 00 00 48 89 fb <48> 8b 8e a8 00 00 00 48 85 c9 74 43 48 89 ca eb 0f 0f 1f 80 00 +[ 532.394036] RIP [] teql_destroy+0x18/0x100 [sch_teql] +[ 532.395127] RSP +[ 532.396179] CR2: 00000000000000a8 + +Null pointer dereference happens on master->slaves dereference in +teql_destroy() as master is null-pointer. + +When qdisc_create() calls teql_qdisc_init() it imediately fails after +check "if (m->dev == dev)" because both devices are teql0, and it does +not set qdisc_priv(sch)->m leaving it zero on error path, then +qdisc_create() imediately calls teql_destroy() which does not expect +zero master pointer and we get OOPS. + +Fixes: 87b60cfacf9f ("net_sched: fix error recovery at qdisc creation") +Signed-off-by: Pavel Tikhomirov +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/sch_teql.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/sched/sch_teql.c ++++ b/net/sched/sch_teql.c +@@ -134,6 +134,9 @@ teql_destroy(struct Qdisc *sch) + struct teql_sched_data *dat = qdisc_priv(sch); + struct teql_master *master = dat->m; + ++ if (!master) ++ return; ++ + prev = master->slaves; + if (prev) { + do { diff --git a/queue-5.4/series b/queue-5.4/series index 3afd8a4b429..41bc997ae44 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -9,8 +9,6 @@ nfc-avoid-endless-loops-caused-by-repeated-llcp_sock_connect.patch xen-evtchn-change-irq_info-lock-to-raw_spinlock_t.patch net-ipv6-check-for-validity-before-dereferencing-cfg-fc_nlinfo.nlh.patch net-dsa-lantiq_gswip-let-gswip-automatically-set-the-xmii-clock.patch -net-dsa-lantiq_gswip-don-t-use-phy-auto-polling.patch -net-dsa-lantiq_gswip-configure-all-remaining-gswip_mii_cfg-bits.patch drm-i915-fix-invalid-access-to-acpi-_dsm-objects.patch gcov-re-fix-clang-11-support.patch ia64-fix-user_stack_pointer-for-ptrace.patch @@ -20,3 +18,19 @@ fs-direct-io-fix-missing-sdio-boundary.patch parisc-parisc-agp-requires-sba-iommu-driver.patch parisc-avoid-a-warning-on-u8-cast-for-cmpxchg-on-u8-pointers.patch arm-dts-turris-omnia-configure-led-intn-pin-as-interrupt-pin.patch +batman-adv-initialize-struct-batadv_tvlv_tt_vlan_data-reserved-field.patch +ice-increase-control-queue-timeout.patch +ice-fix-for-dereference-of-null-pointer.patch +ice-cleanup-fltr-list-in-case-of-allocation-issues.patch +net-hso-fix-null-ptr-deref-during-tty-device-unregistration.patch +ethernet-netronome-nfp-fix-a-use-after-free-in-nfp_bpf_ctrl_msg_rx.patch +bpf-sockmap-fix-sk-prot-unhash-op-reset.patch +net-ensure-mac-header-is-set-in-virtio_net_hdr_to_skb.patch +i40e-fix-sparse-warning-missing-error-code-err.patch +i40e-fix-sparse-error-vsi-netdev-could-be-null.patch +net-sched-sch_teql-fix-null-pointer-dereference.patch +mac80211-fix-txq-ac-confusion.patch +net-hsr-reset-mac-header-for-tx-path.patch +net-ipv6-bugfix-raw-sctp-switch-to-ipv6_can_nonlocal_bind.patch +net-let-skb_orphan_partial-wake-up-waiters.patch +net-sched-fix-action-overwrite-reference-counting.patch