--- /dev/null
+From 08c27f3322fec11950b8f1384aa0f3b11d028528 Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Mon, 5 Apr 2021 19:16:50 +0900
+Subject: batman-adv: initialize "struct batadv_tvlv_tt_vlan_data"->reserved field
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+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 <syzbot+50ee810676e6a089487b@syzkaller.appspotmail.com>
+Tested-by: syzbot <syzbot+50ee810676e6a089487b@syzkaller.appspotmail.com>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+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 <sven@narfation.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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++;
+ }
--- /dev/null
+From 1c84b33101c82683dee8b06761ca1f69e78c8ee7 Mon Sep 17 00:00:00 2001
+From: John Fastabend <john.fastabend@gmail.com>
+Date: Thu, 1 Apr 2021 15:00:19 -0700
+Subject: bpf, sockmap: Fix sk->prot unhash op reset
+
+From: John Fastabend <john.fastabend@gmail.com>
+
+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 <xiyou.wangcong@gmail.com>
+Reported-by: Lorenz Bauer <lmb@cloudflare.com>
+Suggested-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: John Fastabend <john.fastabend@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/161731441904.68884.15593917809745631972.stgit@john-XPS-13-9370
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 {
--- /dev/null
+From 6e5a03bcba44e080a6bf300194a68ce9bb1e5184 Mon Sep 17 00:00:00 2001
+From: Lv Yunlong <lyl2019@mail.ustc.edu.cn>
+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 <lyl2019@mail.ustc.edu.cn>
+
+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 <lyl2019@mail.ustc.edu.cn>
+Reviewed-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
--- /dev/null
+From 6b5674fe6b9bf05394886ebcec62b2d7dae88c42 Mon Sep 17 00:00:00 2001
+From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Date: Fri, 26 Mar 2021 19:43:42 +0100
+Subject: i40e: Fix sparse error: 'vsi->netdev' could be null
+
+From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+
+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 <aleksandr.loktionov@intel.com>
+Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Tested-by: Dave Switzer <david.switzer@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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");
+ }
+ }
--- /dev/null
+From 8a1e918d833ca5c391c4ded5dc006e2d1ce6d37c Mon Sep 17 00:00:00 2001
+From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Date: Fri, 26 Mar 2021 19:43:43 +0100
+Subject: i40e: Fix sparse warning: missing error code 'err'
+
+From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+
+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 <aleksandr.loktionov@intel.com>
+Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Tested-by: Dave Switzer <david.switzer@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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)
--- /dev/null
+From b7eeb52721fe417730fc5adc5cbeeb5fe349ab26 Mon Sep 17 00:00:00 2001
+From: Robert Malz <robertx.malz@intel.com>
+Date: Fri, 26 Feb 2021 13:19:32 -0800
+Subject: ice: Cleanup fltr list in case of allocation issues
+
+From: Robert Malz <robertx.malz@intel.com>
+
+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 <robertx.malz@intel.com>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
--- /dev/null
+From 7a91d3f02b04b2fb18c2dfa8b6c4e5a40a2753f5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jacek=20Bu=C5=82atek?= <jacekx.bulatek@intel.com>
+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 <jacekx.bulatek@intel.com>
+
+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 <jacekx.bulatek@intel.com>
+Co-developed-by: Haiyue Wang <haiyue.wang@intel.com>
+Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+ }
--- /dev/null
+From f88c529ac77b3c21819d2cf1dfcfae1937849743 Mon Sep 17 00:00:00 2001
+From: Fabio Pricoco <fabio.pricoco@intel.com>
+Date: Fri, 26 Feb 2021 13:19:24 -0800
+Subject: ice: Increase control queue timeout
+
+From: Fabio Pricoco <fabio.pricoco@intel.com>
+
+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 <fabio.pricoco@intel.com>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 {
--- /dev/null
+From 1153a74768a9212daadbb50767aa400bc6a0c9b0 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+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 <johannes.berg@intel.com>
+
+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 <toke@redhat.com>
+Link: https://lore.kernel.org/r/20210323210500.bf4d50afea4a.I136ffde910486301f8818f5442e3c9bf8670a9c4@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+ }
+++ /dev/null
-From 4b5923249b8fa427943b50b8f35265176472be38 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Thu, 8 Apr 2021 20:38:28 +0200
-Subject: net: dsa: lantiq_gswip: Configure all remaining GSWIP_MII_CFG bits
-
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-
-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 <hauke@hauke-m.de>
-Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- 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:
+++ /dev/null
-From 3e9005be87777afc902b9f5497495898202d335d Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Thu, 8 Apr 2021 20:38:27 +0200
-Subject: net: dsa: lantiq_gswip: Don't use PHY auto polling
-
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-
-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 <hauke@hauke-m.de>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- 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);
- }
-
--- /dev/null
+From 61431a5907fc36d0738e9a547c7e1556349a03e9 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+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 <edumazet@google.com>
+
+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 <edumazet@google.com>
+Cc: Balazs Nemeth <bnemeth@redhat.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
--- /dev/null
+From 8a12f8836145ffe37e9c8733dce18c22fb668b66 Mon Sep 17 00:00:00 2001
+From: Anirudh Rayabharam <mail@anirudhrb.com>
+Date: Wed, 7 Apr 2021 22:57:22 +0530
+Subject: net: hso: fix null-ptr-deref during tty device unregistration
+
+From: Anirudh Rayabharam <mail@anirudhrb.com>
+
+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 <gregkh@linuxfoundation.org>
+Signed-off-by: Anirudh Rayabharam <mail@anirudhrb.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+ }
+ }
+
--- /dev/null
+From 9d6803921a16f4d768dc41a75375629828f4d91e Mon Sep 17 00:00:00 2001
+From: Kurt Kanzenbach <kurt@linutronix.de>
+Date: Tue, 6 Apr 2021 09:35:09 +0200
+Subject: net: hsr: Reset MAC header for Tx path
+
+From: Kurt Kanzenbach <kurt@linutronix.de>
+
+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 <kurt@linutronix.de>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
--- /dev/null
+From 630e4576f83accf90366686f39808d665d8dbecc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= <maze@google.com>
+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 <maze@google.com>
+
+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 <lorenzo@google.com>
+Fixes: 83ba4645152d ("net: add helpers checking if socket can be bound to nonlocal address")
+Signed-off-by: Maciej Żenczykowski <maze@google.com>
+Reviewed-By: Lorenzo Colitti <lorenzo@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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();
--- /dev/null
+From 9adc89af724f12a03b47099cd943ed54e877cd59 Mon Sep 17 00:00:00 2001
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Tue, 30 Mar 2021 18:43:54 +0200
+Subject: net: let skb_orphan_partial wake-up waiters.
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+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 <edumazet@google.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+
--- /dev/null
+From 87c750e8c38bce706eb32e4d8f1e3402f2cebbd4 Mon Sep 17 00:00:00 2001
+From: Vlad Buslov <vladbu@nvidia.com>
+Date: Wed, 7 Apr 2021 18:36:03 +0300
+Subject: net: sched: fix action overwrite reference counting
+
+From: Vlad Buslov <vladbu@nvidia.com>
+
+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 <memxor@gmail.com>
+Signed-off-by: Vlad Buslov <vladbu@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+
--- /dev/null
+From 1ffbc7ea91606e4abd10eb60de5367f1c86daf5e Mon Sep 17 00:00:00 2001
+From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+Date: Thu, 8 Apr 2021 18:14:31 +0300
+Subject: net: sched: sch_teql: fix null-pointer dereference
+
+From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+
+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: [<ffffffffc06124a8>] 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:[<ffffffffc06124a8>] [<ffffffffc06124a8>] 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] [<ffffffff84c8192e>] qdisc_create+0x36e/0x450
+[ 532.369268] [<ffffffff846a9b49>] ? ns_capable+0x29/0x50
+[ 532.369366] [<ffffffff849afde2>] ? nla_parse+0x32/0x120
+[ 532.369442] [<ffffffff84c81b4c>] tc_modify_qdisc+0x13c/0x610
+[ 532.371508] [<ffffffff84c693e7>] rtnetlink_rcv_msg+0xa7/0x260
+[ 532.372668] [<ffffffff84907b65>] ? sock_has_perm+0x75/0x90
+[ 532.373790] [<ffffffff84c69340>] ? rtnl_newlink+0x890/0x890
+[ 532.374914] [<ffffffff84c8da7b>] netlink_rcv_skb+0xab/0xc0
+[ 532.376055] [<ffffffff84c63708>] rtnetlink_rcv+0x28/0x30
+[ 532.377204] [<ffffffff84c8d400>] netlink_unicast+0x170/0x210
+[ 532.378333] [<ffffffff84c8d7a8>] netlink_sendmsg+0x308/0x420
+[ 532.379465] [<ffffffff84c2f3a6>] sock_sendmsg+0xb6/0xf0
+[ 532.380710] [<ffffffffc034a56e>] ? __xfs_filemap_fault+0x8e/0x1d0 [xfs]
+[ 532.381868] [<ffffffffc034a75c>] ? xfs_filemap_fault+0x2c/0x30 [xfs]
+[ 532.383037] [<ffffffff847ec23a>] ? __do_fault.isra.61+0x8a/0x100
+[ 532.384144] [<ffffffff84c30269>] ___sys_sendmsg+0x3e9/0x400
+[ 532.385268] [<ffffffff847f3fad>] ? handle_mm_fault+0x39d/0x9b0
+[ 532.386387] [<ffffffff84d88678>] ? __do_page_fault+0x238/0x500
+[ 532.387472] [<ffffffff84c31921>] __sys_sendmsg+0x51/0x90
+[ 532.388560] [<ffffffff84c31972>] SyS_sendmsg+0x12/0x20
+[ 532.389636] [<ffffffff84d8dede>] system_call_fastpath+0x25/0x2a
+[ 532.390704] [<ffffffff84d8de21>] ? 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 [<ffffffffc06124a8>] teql_destroy+0x18/0x100 [sch_teql]
+[ 532.395127] RSP <ffff8b7c9fdbf8e0>
+[ 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 <ptikhomirov@virtuozzo.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 {
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
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