]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Jan 2022 13:54:34 +0000 (14:54 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Jan 2022 13:54:34 +0000 (14:54 +0100)
added patches:
batman-adv-mcast-don-t-send-link-local-multicast-to-mcast-routers.patch
ftrace-samples-add-missing-prototypes-direct-functions.patch
i40e-fix-for-displaying-message-regarding-nvm-version.patch
i40e-fix-incorrect-netdev-s-real-number-of-rx-tx-queues.patch
i40e-fix-use-after-free-in-i40e_sync_filters_subtask.patch
ipv4-check-attribute-length-for-rta_flow-in-multipath-route.patch
ipv4-check-attribute-length-for-rta_gateway-in-multipath-route.patch
ipv6-check-attribute-length-for-rta_gateway-in-multipath-route.patch
ipv6-check-attribute-length-for-rta_gateway-when-deleting-multipath-route.patch
lwtunnel-validate-rta_encap_type-attribute-length.patch
net-ena-fix-error-handling-when-calculating-max-io-queues-number.patch
net-ena-fix-undefined-state-when-tx-request-id-is-out-of-bounds.patch
net-ena-fix-wrong-rx-request-id-by-resetting-device.patch
sch_qfq-prevent-shift-out-of-bounds-in-qfq_init_qdisc.patch
sctp-hold-endpoint-before-calling-cb-in-sctp_transport_lookup_process.patch
selftests-net-udpgro_fwd.sh-explicitly-checking-the-available-ping-feature.patch
sfc-the-rx-page_ring-is-optional.patch

18 files changed:
queue-5.15/batman-adv-mcast-don-t-send-link-local-multicast-to-mcast-routers.patch [new file with mode: 0644]
queue-5.15/ftrace-samples-add-missing-prototypes-direct-functions.patch [new file with mode: 0644]
queue-5.15/i40e-fix-for-displaying-message-regarding-nvm-version.patch [new file with mode: 0644]
queue-5.15/i40e-fix-incorrect-netdev-s-real-number-of-rx-tx-queues.patch [new file with mode: 0644]
queue-5.15/i40e-fix-use-after-free-in-i40e_sync_filters_subtask.patch [new file with mode: 0644]
queue-5.15/ipv4-check-attribute-length-for-rta_flow-in-multipath-route.patch [new file with mode: 0644]
queue-5.15/ipv4-check-attribute-length-for-rta_gateway-in-multipath-route.patch [new file with mode: 0644]
queue-5.15/ipv6-check-attribute-length-for-rta_gateway-in-multipath-route.patch [new file with mode: 0644]
queue-5.15/ipv6-check-attribute-length-for-rta_gateway-when-deleting-multipath-route.patch [new file with mode: 0644]
queue-5.15/lwtunnel-validate-rta_encap_type-attribute-length.patch [new file with mode: 0644]
queue-5.15/net-ena-fix-error-handling-when-calculating-max-io-queues-number.patch [new file with mode: 0644]
queue-5.15/net-ena-fix-undefined-state-when-tx-request-id-is-out-of-bounds.patch [new file with mode: 0644]
queue-5.15/net-ena-fix-wrong-rx-request-id-by-resetting-device.patch [new file with mode: 0644]
queue-5.15/sch_qfq-prevent-shift-out-of-bounds-in-qfq_init_qdisc.patch [new file with mode: 0644]
queue-5.15/sctp-hold-endpoint-before-calling-cb-in-sctp_transport_lookup_process.patch [new file with mode: 0644]
queue-5.15/selftests-net-udpgro_fwd.sh-explicitly-checking-the-available-ping-feature.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/sfc-the-rx-page_ring-is-optional.patch [new file with mode: 0644]

diff --git a/queue-5.15/batman-adv-mcast-don-t-send-link-local-multicast-to-mcast-routers.patch b/queue-5.15/batman-adv-mcast-don-t-send-link-local-multicast-to-mcast-routers.patch
new file mode 100644 (file)
index 0000000..99f908a
--- /dev/null
@@ -0,0 +1,179 @@
+From 938f2e0b57ffe8a6df71e1e177b2978b1b33fe5e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue>
+Date: Sat, 1 Jan 2022 06:27:13 +0100
+Subject: batman-adv: mcast: don't send link-local multicast to mcast routers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Linus Lüssing <linus.luessing@c0d3.blue>
+
+commit 938f2e0b57ffe8a6df71e1e177b2978b1b33fe5e upstream.
+
+The addition of routable multicast TX handling introduced a
+bug/regression for packets with a link-local multicast destination:
+These packets would be sent to all batman-adv nodes with a multicast
+router and to all batman-adv nodes with an old version without multicast
+router detection.
+
+This even disregards the batman-adv multicast fanout setting, which can
+potentially lead to an unwanted, high number of unicast transmissions or
+even congestion.
+
+Fixing this by avoiding to send link-local multicast packets to nodes in
+the multicast router list.
+
+Fixes: 11d458c1cb9b ("batman-adv: mcast: apply optimizations for routable packets, too")
+Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/multicast.c      |   15 ++++++++++-----
+ net/batman-adv/multicast.h      |   10 ++++++----
+ net/batman-adv/soft-interface.c |    7 +++++--
+ 3 files changed, 21 insertions(+), 11 deletions(-)
+
+--- a/net/batman-adv/multicast.c
++++ b/net/batman-adv/multicast.c
+@@ -1339,6 +1339,7 @@ batadv_mcast_forw_rtr_node_get(struct ba
+  * @bat_priv: the bat priv with all the soft interface information
+  * @skb: The multicast packet to check
+  * @orig: an originator to be set to forward the skb to
++ * @is_routable: stores whether the destination is routable
+  *
+  * Return: the forwarding mode as enum batadv_forw_mode and in case of
+  * BATADV_FORW_SINGLE set the orig to the single originator the skb
+@@ -1346,17 +1347,16 @@ batadv_mcast_forw_rtr_node_get(struct ba
+  */
+ enum batadv_forw_mode
+ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
+-                     struct batadv_orig_node **orig)
++                     struct batadv_orig_node **orig, int *is_routable)
+ {
+       int ret, tt_count, ip_count, unsnoop_count, total_count;
+       bool is_unsnoopable = false;
+       unsigned int mcast_fanout;
+       struct ethhdr *ethhdr;
+-      int is_routable = 0;
+       int rtr_count = 0;
+       ret = batadv_mcast_forw_mode_check(bat_priv, skb, &is_unsnoopable,
+-                                         &is_routable);
++                                         is_routable);
+       if (ret == -ENOMEM)
+               return BATADV_FORW_NONE;
+       else if (ret < 0)
+@@ -1369,7 +1369,7 @@ batadv_mcast_forw_mode(struct batadv_pri
+       ip_count = batadv_mcast_forw_want_all_ip_count(bat_priv, ethhdr);
+       unsnoop_count = !is_unsnoopable ? 0 :
+                       atomic_read(&bat_priv->mcast.num_want_all_unsnoopables);
+-      rtr_count = batadv_mcast_forw_rtr_count(bat_priv, is_routable);
++      rtr_count = batadv_mcast_forw_rtr_count(bat_priv, *is_routable);
+       total_count = tt_count + ip_count + unsnoop_count + rtr_count;
+@@ -1689,6 +1689,7 @@ batadv_mcast_forw_want_rtr(struct batadv
+  * @bat_priv: the bat priv with all the soft interface information
+  * @skb: the multicast packet to transmit
+  * @vid: the vlan identifier
++ * @is_routable: stores whether the destination is routable
+  *
+  * Sends copies of a frame with multicast destination to any node that signaled
+  * interest in it, that is either via the translation table or the according
+@@ -1701,7 +1702,7 @@ batadv_mcast_forw_want_rtr(struct batadv
+  * is neither IPv4 nor IPv6. NET_XMIT_SUCCESS otherwise.
+  */
+ int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
+-                         unsigned short vid)
++                         unsigned short vid, int is_routable)
+ {
+       int ret;
+@@ -1717,12 +1718,16 @@ int batadv_mcast_forw_send(struct batadv
+               return ret;
+       }
++      if (!is_routable)
++              goto skip_mc_router;
++
+       ret = batadv_mcast_forw_want_rtr(bat_priv, skb, vid);
+       if (ret != NET_XMIT_SUCCESS) {
+               kfree_skb(skb);
+               return ret;
+       }
++skip_mc_router:
+       consume_skb(skb);
+       return ret;
+ }
+--- a/net/batman-adv/multicast.h
++++ b/net/batman-adv/multicast.h
+@@ -43,7 +43,8 @@ enum batadv_forw_mode {
+ enum batadv_forw_mode
+ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
+-                     struct batadv_orig_node **mcast_single_orig);
++                     struct batadv_orig_node **mcast_single_orig,
++                     int *is_routable);
+ int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
+                               struct sk_buff *skb,
+@@ -51,7 +52,7 @@ int batadv_mcast_forw_send_orig(struct b
+                               struct batadv_orig_node *orig_node);
+ int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
+-                         unsigned short vid);
++                         unsigned short vid, int is_routable);
+ void batadv_mcast_init(struct batadv_priv *bat_priv);
+@@ -68,7 +69,8 @@ void batadv_mcast_purge_orig(struct bata
+ static inline enum batadv_forw_mode
+ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
+-                     struct batadv_orig_node **mcast_single_orig)
++                     struct batadv_orig_node **mcast_single_orig,
++                     int *is_routable)
+ {
+       return BATADV_FORW_ALL;
+ }
+@@ -85,7 +87,7 @@ batadv_mcast_forw_send_orig(struct batad
+ static inline int
+ batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
+-                     unsigned short vid)
++                     unsigned short vid, int is_routable)
+ {
+       kfree_skb(skb);
+       return NET_XMIT_DROP;
+--- a/net/batman-adv/soft-interface.c
++++ b/net/batman-adv/soft-interface.c
+@@ -198,6 +198,7 @@ static netdev_tx_t batadv_interface_tx(s
+       int gw_mode;
+       enum batadv_forw_mode forw_mode = BATADV_FORW_SINGLE;
+       struct batadv_orig_node *mcast_single_orig = NULL;
++      int mcast_is_routable = 0;
+       int network_offset = ETH_HLEN;
+       __be16 proto;
+@@ -300,7 +301,8 @@ static netdev_tx_t batadv_interface_tx(s
+ send:
+               if (do_bcast && !is_broadcast_ether_addr(ethhdr->h_dest)) {
+                       forw_mode = batadv_mcast_forw_mode(bat_priv, skb,
+-                                                         &mcast_single_orig);
++                                                         &mcast_single_orig,
++                                                         &mcast_is_routable);
+                       if (forw_mode == BATADV_FORW_NONE)
+                               goto dropped;
+@@ -359,7 +361,8 @@ send:
+                       ret = batadv_mcast_forw_send_orig(bat_priv, skb, vid,
+                                                         mcast_single_orig);
+               } else if (forw_mode == BATADV_FORW_SOME) {
+-                      ret = batadv_mcast_forw_send(bat_priv, skb, vid);
++                      ret = batadv_mcast_forw_send(bat_priv, skb, vid,
++                                                   mcast_is_routable);
+               } else {
+                       if (batadv_dat_snoop_outgoing_arp_request(bat_priv,
+                                                                 skb))
diff --git a/queue-5.15/ftrace-samples-add-missing-prototypes-direct-functions.patch b/queue-5.15/ftrace-samples-add-missing-prototypes-direct-functions.patch
new file mode 100644 (file)
index 0000000..8340dbc
--- /dev/null
@@ -0,0 +1,76 @@
+From 0daf5cb217a9ca8ae91b8f966ddae322699fb71d Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Sun, 19 Dec 2021 14:53:17 +0100
+Subject: ftrace/samples: Add missing prototypes direct functions
+
+From: Jiri Olsa <jolsa@redhat.com>
+
+commit 0daf5cb217a9ca8ae91b8f966ddae322699fb71d upstream.
+
+There's another compilation fail (first here [1]) reported by kernel
+test robot for W=1 clang build:
+
+  >> samples/ftrace/ftrace-direct-multi-modify.c:7:6: warning: no previous
+  prototype for function 'my_direct_func1' [-Wmissing-prototypes]
+     void my_direct_func1(unsigned long ip)
+
+Direct functions in ftrace direct sample modules need to have prototypes
+defined. They are already global in order to be visible for the inline
+assembly, so there's no problem.
+
+The kernel test robot reported just error for ftrace-direct-multi-modify,
+but I got same errors also for the rest of the modules touched by this patch.
+
+[1] 67d4f6e3bf5d ftrace/samples: Add missing prototype for my_direct_func
+
+Link: https://lkml.kernel.org/r/20211219135317.212430-1-jolsa@kernel.org
+
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: e1067a07cfbc ("ftrace/samples: Add module to test multi direct modify interface")
+Fixes: ae0cc3b7e7f5 ("ftrace/samples: Add a sample module that implements modify_ftrace_direct()")
+Fixes: 156473a0ff4f ("ftrace: Add another example of register_ftrace_direct() use case")
+Fixes: b06457c83af6 ("ftrace: Add sample module that uses register_ftrace_direct()")
+Signed-off-by: Jiri Olsa <jolsa@kernel.org>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ samples/ftrace/ftrace-direct-modify.c |    3 +++
+ samples/ftrace/ftrace-direct-too.c    |    3 +++
+ samples/ftrace/ftrace-direct.c        |    2 ++
+ 3 files changed, 8 insertions(+)
+
+--- a/samples/ftrace/ftrace-direct-modify.c
++++ b/samples/ftrace/ftrace-direct-modify.c
+@@ -3,6 +3,9 @@
+ #include <linux/kthread.h>
+ #include <linux/ftrace.h>
++extern void my_direct_func1(void);
++extern void my_direct_func2(void);
++
+ void my_direct_func1(void)
+ {
+       trace_printk("my direct func1\n");
+--- a/samples/ftrace/ftrace-direct-too.c
++++ b/samples/ftrace/ftrace-direct-too.c
+@@ -4,6 +4,9 @@
+ #include <linux/mm.h> /* for handle_mm_fault() */
+ #include <linux/ftrace.h>
++extern void my_direct_func(struct vm_area_struct *vma,
++                         unsigned long address, unsigned int flags);
++
+ void my_direct_func(struct vm_area_struct *vma,
+                       unsigned long address, unsigned int flags)
+ {
+--- a/samples/ftrace/ftrace-direct.c
++++ b/samples/ftrace/ftrace-direct.c
+@@ -4,6 +4,8 @@
+ #include <linux/sched.h> /* for wake_up_process() */
+ #include <linux/ftrace.h>
++extern void my_direct_func(struct task_struct *p);
++
+ void my_direct_func(struct task_struct *p)
+ {
+       trace_printk("waking up %s-%d\n", p->comm, p->pid);
diff --git a/queue-5.15/i40e-fix-for-displaying-message-regarding-nvm-version.patch b/queue-5.15/i40e-fix-for-displaying-message-regarding-nvm-version.patch
new file mode 100644 (file)
index 0000000..13bb7e4
--- /dev/null
@@ -0,0 +1,39 @@
+From 40feded8a247f95957a0de9abd100085fb320a2f Mon Sep 17 00:00:00 2001
+From: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Date: Thu, 9 Dec 2021 11:04:35 +0100
+Subject: i40e: Fix for displaying message regarding NVM version
+
+From: Mateusz Palczewski <mateusz.palczewski@intel.com>
+
+commit 40feded8a247f95957a0de9abd100085fb320a2f upstream.
+
+When loading the i40e driver, it prints a message like: 'The driver for the
+device detected a newer version of the NVM image v1.x than expected v1.y.
+Please install the most recent version of the network driver.' This is
+misleading as the driver is working as expected.
+
+Fix that by removing the second part of message and changing it from
+dev_info to dev_dbg.
+
+Fixes: 4fb29bddb57f ("i40e: The driver now prints the API version in error message")
+Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Tested-by: Gurucharan G <gurucharanx.g@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 |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -15475,8 +15475,8 @@ static int i40e_probe(struct pci_dev *pd
+       if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
+           hw->aq.api_min_ver > I40E_FW_MINOR_VERSION(hw))
+-              dev_info(&pdev->dev,
+-                       "The driver for the device detected a newer version of the NVM image v%u.%u than expected v%u.%u. Please install the most recent version of the network driver.\n",
++              dev_dbg(&pdev->dev,
++                      "The driver for the device detected a newer version of the NVM image v%u.%u than v%u.%u.\n",
+                        hw->aq.api_maj_ver,
+                        hw->aq.api_min_ver,
+                        I40E_FW_API_VERSION_MAJOR,
diff --git a/queue-5.15/i40e-fix-incorrect-netdev-s-real-number-of-rx-tx-queues.patch b/queue-5.15/i40e-fix-incorrect-netdev-s-real-number-of-rx-tx-queues.patch
new file mode 100644 (file)
index 0000000..604fa73
--- /dev/null
@@ -0,0 +1,86 @@
+From e738451d78b2f8a9635d66c6a87f304b4d965f7a Mon Sep 17 00:00:00 2001
+From: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+Date: Fri, 17 Dec 2021 14:29:05 +0000
+Subject: i40e: Fix incorrect netdev's real number of RX/TX queues
+
+From: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+
+commit e738451d78b2f8a9635d66c6a87f304b4d965f7a upstream.
+
+There was a wrong queues representation in sysfs during
+driver's reinitialization in case of online cpus number is
+less than combined queues. It was caused by stopped
+NetworkManager, which is responsible for calling vsi_open
+function during driver's initialization.
+In specific situation (ex. 12 cpus online) there were 16 queues
+in /sys/class/net/<iface>/queues. In case of modifying queues with
+value higher, than number of online cpus, then it caused write
+errors and other errors.
+Add updating of sysfs's queues representation during driver
+initialization.
+
+Fixes: 41c445ff0f48 ("i40e: main driver core")
+Signed-off-by: Lukasz Cieplicki <lukaszx.cieplicki@intel.com>
+Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+Tested-by: Gurucharan G <gurucharanx.g@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 |   32 +++++++++++++++++++++-------
+ 1 file changed, 25 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -8741,6 +8741,27 @@ int i40e_open(struct net_device *netdev)
+ }
+ /**
++ * i40e_netif_set_realnum_tx_rx_queues - Update number of tx/rx queues
++ * @vsi: vsi structure
++ *
++ * This updates netdev's number of tx/rx queues
++ *
++ * Returns status of setting tx/rx queues
++ **/
++static int i40e_netif_set_realnum_tx_rx_queues(struct i40e_vsi *vsi)
++{
++      int ret;
++
++      ret = netif_set_real_num_rx_queues(vsi->netdev,
++                                         vsi->num_queue_pairs);
++      if (ret)
++              return ret;
++
++      return netif_set_real_num_tx_queues(vsi->netdev,
++                                          vsi->num_queue_pairs);
++}
++
++/**
+  * i40e_vsi_open -
+  * @vsi: the VSI to open
+  *
+@@ -8776,13 +8797,7 @@ int i40e_vsi_open(struct i40e_vsi *vsi)
+                       goto err_setup_rx;
+               /* Notify the stack of the actual queue counts. */
+-              err = netif_set_real_num_tx_queues(vsi->netdev,
+-                                                 vsi->num_queue_pairs);
+-              if (err)
+-                      goto err_set_queues;
+-
+-              err = netif_set_real_num_rx_queues(vsi->netdev,
+-                                                 vsi->num_queue_pairs);
++              err = i40e_netif_set_realnum_tx_rx_queues(vsi);
+               if (err)
+                       goto err_set_queues;
+@@ -14175,6 +14190,9 @@ struct i40e_vsi *i40e_vsi_setup(struct i
+               ret = i40e_config_netdev(vsi);
+               if (ret)
+                       goto err_netdev;
++              ret = i40e_netif_set_realnum_tx_rx_queues(vsi);
++              if (ret)
++                      goto err_netdev;
+               ret = register_netdev(vsi->netdev);
+               if (ret)
+                       goto err_netdev;
diff --git a/queue-5.15/i40e-fix-use-after-free-in-i40e_sync_filters_subtask.patch b/queue-5.15/i40e-fix-use-after-free-in-i40e_sync_filters_subtask.patch
new file mode 100644 (file)
index 0000000..6796a4b
--- /dev/null
@@ -0,0 +1,138 @@
+From 3116f59c12bd24c513194cd3acb3ec1f7d468954 Mon Sep 17 00:00:00 2001
+From: Di Zhu <zhudi2@huawei.com>
+Date: Mon, 29 Nov 2021 19:52:01 +0600
+Subject: i40e: fix use-after-free in i40e_sync_filters_subtask()
+
+From: Di Zhu <zhudi2@huawei.com>
+
+commit 3116f59c12bd24c513194cd3acb3ec1f7d468954 upstream.
+
+Using ifconfig command to delete the ipv6 address will cause
+the i40e network card driver to delete its internal mac_filter and
+i40e_service_task kernel thread will concurrently access the mac_filter.
+These two processes are not protected by lock
+so causing the following use-after-free problems.
+
+ print_address_description+0x70/0x360
+ ? vprintk_func+0x5e/0xf0
+ kasan_report+0x1b2/0x330
+ i40e_sync_vsi_filters+0x4f0/0x1850 [i40e]
+ i40e_sync_filters_subtask+0xe3/0x130 [i40e]
+ i40e_service_task+0x195/0x24c0 [i40e]
+ process_one_work+0x3f5/0x7d0
+ worker_thread+0x61/0x6c0
+ ? process_one_work+0x7d0/0x7d0
+ kthread+0x1c3/0x1f0
+ ? kthread_park+0xc0/0xc0
+ ret_from_fork+0x35/0x40
+
+Allocated by task 2279810:
+ kasan_kmalloc+0xa0/0xd0
+ kmem_cache_alloc_trace+0xf3/0x1e0
+ i40e_add_filter+0x127/0x2b0 [i40e]
+ i40e_add_mac_filter+0x156/0x190 [i40e]
+ i40e_addr_sync+0x2d/0x40 [i40e]
+ __hw_addr_sync_dev+0x154/0x210
+ i40e_set_rx_mode+0x6d/0xf0 [i40e]
+ __dev_set_rx_mode+0xfb/0x1f0
+ __dev_mc_add+0x6c/0x90
+ igmp6_group_added+0x214/0x230
+ __ipv6_dev_mc_inc+0x338/0x4f0
+ addrconf_join_solict.part.7+0xa2/0xd0
+ addrconf_dad_work+0x500/0x980
+ process_one_work+0x3f5/0x7d0
+ worker_thread+0x61/0x6c0
+ kthread+0x1c3/0x1f0
+ ret_from_fork+0x35/0x40
+
+Freed by task 2547073:
+ __kasan_slab_free+0x130/0x180
+ kfree+0x90/0x1b0
+ __i40e_del_filter+0xa3/0xf0 [i40e]
+ i40e_del_mac_filter+0xf3/0x130 [i40e]
+ i40e_addr_unsync+0x85/0xa0 [i40e]
+ __hw_addr_sync_dev+0x9d/0x210
+ i40e_set_rx_mode+0x6d/0xf0 [i40e]
+ __dev_set_rx_mode+0xfb/0x1f0
+ __dev_mc_del+0x69/0x80
+ igmp6_group_dropped+0x279/0x510
+ __ipv6_dev_mc_dec+0x174/0x220
+ addrconf_leave_solict.part.8+0xa2/0xd0
+ __ipv6_ifa_notify+0x4cd/0x570
+ ipv6_ifa_notify+0x58/0x80
+ ipv6_del_addr+0x259/0x4a0
+ inet6_addr_del+0x188/0x260
+ addrconf_del_ifaddr+0xcc/0x130
+ inet6_ioctl+0x152/0x190
+ sock_do_ioctl+0xd8/0x2b0
+ sock_ioctl+0x2e5/0x4c0
+ do_vfs_ioctl+0x14e/0xa80
+ ksys_ioctl+0x7c/0xa0
+ __x64_sys_ioctl+0x42/0x50
+ do_syscall_64+0x98/0x2c0
+ entry_SYSCALL_64_after_hwframe+0x65/0xca
+
+Fixes: 41c445ff0f48 ("i40e: main driver core")
+Signed-off-by: Di Zhu <zhudi2@huawei.com>
+Signed-off-by: Rui Zhang <zhangrui182@huawei.com>
+Tested-by: Gurucharan G <gurucharanx.g@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 |   24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -99,6 +99,24 @@ MODULE_LICENSE("GPL v2");
+ static struct workqueue_struct *i40e_wq;
++static void netdev_hw_addr_refcnt(struct i40e_mac_filter *f,
++                                struct net_device *netdev, int delta)
++{
++      struct netdev_hw_addr *ha;
++
++      if (!f || !netdev)
++              return;
++
++      netdev_for_each_mc_addr(ha, netdev) {
++              if (ether_addr_equal(ha->addr, f->macaddr)) {
++                      ha->refcount += delta;
++                      if (ha->refcount <= 0)
++                              ha->refcount = 1;
++                      break;
++              }
++      }
++}
++
+ /**
+  * i40e_allocate_dma_mem_d - OS specific memory alloc for shared code
+  * @hw:   pointer to the HW structure
+@@ -2036,6 +2054,7 @@ static void i40e_undo_add_filter_entries
+       hlist_for_each_entry_safe(new, h, from, hlist) {
+               /* We can simply free the wrapper structure */
+               hlist_del(&new->hlist);
++              netdev_hw_addr_refcnt(new->f, vsi->netdev, -1);
+               kfree(new);
+       }
+ }
+@@ -2383,6 +2402,10 @@ int i40e_sync_vsi_filters(struct i40e_vs
+                                                      &tmp_add_list,
+                                                      &tmp_del_list,
+                                                      vlan_filters);
++
++              hlist_for_each_entry(new, &tmp_add_list, hlist)
++                      netdev_hw_addr_refcnt(new->f, vsi->netdev, 1);
++
+               if (retval)
+                       goto err_no_memory_locked;
+@@ -2515,6 +2538,7 @@ int i40e_sync_vsi_filters(struct i40e_vs
+                       if (new->f->state == I40E_FILTER_NEW)
+                               new->f->state = new->state;
+                       hlist_del(&new->hlist);
++                      netdev_hw_addr_refcnt(new->f, vsi->netdev, -1);
+                       kfree(new);
+               }
+               spin_unlock_bh(&vsi->mac_filter_hash_lock);
diff --git a/queue-5.15/ipv4-check-attribute-length-for-rta_flow-in-multipath-route.patch b/queue-5.15/ipv4-check-attribute-length-for-rta_flow-in-multipath-route.patch
new file mode 100644 (file)
index 0000000..6ca80b6
--- /dev/null
@@ -0,0 +1,53 @@
+From 664b9c4b7392ce723b013201843264bf95481ce5 Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@kernel.org>
+Date: Thu, 30 Dec 2021 17:36:32 -0700
+Subject: ipv4: Check attribute length for RTA_FLOW in multipath route
+
+From: David Ahern <dsahern@kernel.org>
+
+commit 664b9c4b7392ce723b013201843264bf95481ce5 upstream.
+
+Make sure RTA_FLOW is at least 4B before using.
+
+Fixes: 4e902c57417c ("[IPv4]: FIB configuration using struct fib_config")
+Signed-off-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/fib_semantics.c |   17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+--- a/net/ipv4/fib_semantics.c
++++ b/net/ipv4/fib_semantics.c
+@@ -731,8 +731,13 @@ static int fib_get_nhs(struct fib_info *
+                       }
+                       nla = nla_find(attrs, attrlen, RTA_FLOW);
+-                      if (nla)
++                      if (nla) {
++                              if (nla_len(nla) < sizeof(u32)) {
++                                      NL_SET_ERR_MSG(extack, "Invalid RTA_FLOW");
++                                      return -EINVAL;
++                              }
+                               fib_cfg.fc_flow = nla_get_u32(nla);
++                      }
+                       fib_cfg.fc_encap = nla_find(attrs, attrlen, RTA_ENCAP);
+                       nla = nla_find(attrs, attrlen, RTA_ENCAP_TYPE);
+@@ -963,8 +968,14 @@ int fib_nh_match(struct net *net, struct
+ #ifdef CONFIG_IP_ROUTE_CLASSID
+                       nla = nla_find(attrs, attrlen, RTA_FLOW);
+-                      if (nla && nla_get_u32(nla) != nh->nh_tclassid)
+-                              return 1;
++                      if (nla) {
++                              if (nla_len(nla) < sizeof(u32)) {
++                                      NL_SET_ERR_MSG(extack, "Invalid RTA_FLOW");
++                                      return -EINVAL;
++                              }
++                              if (nla_get_u32(nla) != nh->nh_tclassid)
++                                      return 1;
++                      }
+ #endif
+               }
diff --git a/queue-5.15/ipv4-check-attribute-length-for-rta_gateway-in-multipath-route.patch b/queue-5.15/ipv4-check-attribute-length-for-rta_gateway-in-multipath-route.patch
new file mode 100644 (file)
index 0000000..399bd33
--- /dev/null
@@ -0,0 +1,93 @@
+From 7a3429bace0e08d94c39245631ea6bc109dafa49 Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@kernel.org>
+Date: Thu, 30 Dec 2021 17:36:31 -0700
+Subject: ipv4: Check attribute length for RTA_GATEWAY in multipath route
+
+From: David Ahern <dsahern@kernel.org>
+
+commit 7a3429bace0e08d94c39245631ea6bc109dafa49 upstream.
+
+syzbot reported uninit-value:
+============================================================
+  BUG: KMSAN: uninit-value in fib_get_nhs+0xac4/0x1f80
+  net/ipv4/fib_semantics.c:708
+   fib_get_nhs+0xac4/0x1f80 net/ipv4/fib_semantics.c:708
+   fib_create_info+0x2411/0x4870 net/ipv4/fib_semantics.c:1453
+   fib_table_insert+0x45c/0x3a10 net/ipv4/fib_trie.c:1224
+   inet_rtm_newroute+0x289/0x420 net/ipv4/fib_frontend.c:886
+
+Add helper to validate RTA_GATEWAY length before using the attribute.
+
+Fixes: 4e902c57417c ("[IPv4]: FIB configuration using struct fib_config")
+Reported-by: syzbot+d4b9a2851cc3ce998741@syzkaller.appspotmail.com
+Signed-off-by: David Ahern <dsahern@kernel.org>
+Cc: Thomas Graf <tgraf@suug.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/fib_semantics.c |   29 ++++++++++++++++++++++++++---
+ 1 file changed, 26 insertions(+), 3 deletions(-)
+
+--- a/net/ipv4/fib_semantics.c
++++ b/net/ipv4/fib_semantics.c
+@@ -662,6 +662,19 @@ static int fib_count_nexthops(struct rtn
+       return nhs;
+ }
++static int fib_gw_from_attr(__be32 *gw, struct nlattr *nla,
++                          struct netlink_ext_ack *extack)
++{
++      if (nla_len(nla) < sizeof(*gw)) {
++              NL_SET_ERR_MSG(extack, "Invalid IPv4 address in RTA_GATEWAY");
++              return -EINVAL;
++      }
++
++      *gw = nla_get_in_addr(nla);
++
++      return 0;
++}
++
+ /* only called when fib_nh is integrated into fib_info */
+ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
+                      int remaining, struct fib_config *cfg,
+@@ -704,7 +717,11 @@ static int fib_get_nhs(struct fib_info *
+                               return -EINVAL;
+                       }
+                       if (nla) {
+-                              fib_cfg.fc_gw4 = nla_get_in_addr(nla);
++                              ret = fib_gw_from_attr(&fib_cfg.fc_gw4, nla,
++                                                     extack);
++                              if (ret)
++                                      goto errout;
++
+                               if (fib_cfg.fc_gw4)
+                                       fib_cfg.fc_gw_family = AF_INET;
+                       } else if (nlav) {
+@@ -902,6 +919,7 @@ int fib_nh_match(struct net *net, struct
+               attrlen = rtnh_attrlen(rtnh);
+               if (attrlen > 0) {
+                       struct nlattr *nla, *nlav, *attrs = rtnh_attrs(rtnh);
++                      int err;
+                       nla = nla_find(attrs, attrlen, RTA_GATEWAY);
+                       nlav = nla_find(attrs, attrlen, RTA_VIA);
+@@ -912,12 +930,17 @@ int fib_nh_match(struct net *net, struct
+                       }
+                       if (nla) {
++                              __be32 gw;
++
++                              err = fib_gw_from_attr(&gw, nla, extack);
++                              if (err)
++                                      return err;
++
+                               if (nh->fib_nh_gw_family != AF_INET ||
+-                                  nla_get_in_addr(nla) != nh->fib_nh_gw4)
++                                  gw != nh->fib_nh_gw4)
+                                       return 1;
+                       } else if (nlav) {
+                               struct fib_config cfg2;
+-                              int err;
+                               err = fib_gw_from_via(&cfg2, nlav, extack);
+                               if (err)
diff --git a/queue-5.15/ipv6-check-attribute-length-for-rta_gateway-in-multipath-route.patch b/queue-5.15/ipv6-check-attribute-length-for-rta_gateway-in-multipath-route.patch
new file mode 100644 (file)
index 0000000..a4fc5b4
--- /dev/null
@@ -0,0 +1,60 @@
+From 4619bcf91399f00a40885100fb61d594d8454033 Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@kernel.org>
+Date: Thu, 30 Dec 2021 17:36:33 -0700
+Subject: ipv6: Check attribute length for RTA_GATEWAY in multipath route
+
+From: David Ahern <dsahern@kernel.org>
+
+commit 4619bcf91399f00a40885100fb61d594d8454033 upstream.
+
+Commit referenced in the Fixes tag used nla_memcpy for RTA_GATEWAY as
+does the current nla_get_in6_addr. nla_memcpy protects against accessing
+memory greater than what is in the attribute, but there is no check
+requiring the attribute to have an IPv6 address. Add it.
+
+Fixes: 51ebd3181572 ("ipv6: add support of equal cost multipath (ECMP)")
+Signed-off-by: David Ahern <dsahern@kernel.org>
+Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/route.c |   21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -5224,6 +5224,19 @@ out:
+       return should_notify;
+ }
++static int fib6_gw_from_attr(struct in6_addr *gw, struct nlattr *nla,
++                           struct netlink_ext_ack *extack)
++{
++      if (nla_len(nla) < sizeof(*gw)) {
++              NL_SET_ERR_MSG(extack, "Invalid IPv6 address in RTA_GATEWAY");
++              return -EINVAL;
++      }
++
++      *gw = nla_get_in6_addr(nla);
++
++      return 0;
++}
++
+ static int ip6_route_multipath_add(struct fib6_config *cfg,
+                                  struct netlink_ext_ack *extack)
+ {
+@@ -5264,7 +5277,13 @@ static int ip6_route_multipath_add(struc
+                       nla = nla_find(attrs, attrlen, RTA_GATEWAY);
+                       if (nla) {
+-                              r_cfg.fc_gateway = nla_get_in6_addr(nla);
++                              int ret;
++
++                              ret = fib6_gw_from_attr(&r_cfg.fc_gateway, nla,
++                                                      extack);
++                              if (ret)
++                                      return ret;
++
+                               r_cfg.fc_flags |= RTF_GATEWAY;
+                       }
+                       r_cfg.fc_encap = nla_find(attrs, attrlen, RTA_ENCAP);
diff --git a/queue-5.15/ipv6-check-attribute-length-for-rta_gateway-when-deleting-multipath-route.patch b/queue-5.15/ipv6-check-attribute-length-for-rta_gateway-when-deleting-multipath-route.patch
new file mode 100644 (file)
index 0000000..1f3bde9
--- /dev/null
@@ -0,0 +1,36 @@
+From 1ff15a710a862db1101b97810af14aedc835a86a Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@kernel.org>
+Date: Thu, 30 Dec 2021 17:36:34 -0700
+Subject: ipv6: Check attribute length for RTA_GATEWAY when deleting multipath route
+
+From: David Ahern <dsahern@kernel.org>
+
+commit 1ff15a710a862db1101b97810af14aedc835a86a upstream.
+
+Make sure RTA_GATEWAY for IPv6 multipath route has enough bytes to hold
+an IPv6 address.
+
+Fixes: 6b9ea5a64ed5 ("ipv6: fix multipath route replace error recovery")
+Signed-off-by: David Ahern <dsahern@kernel.org>
+Cc: Roopa Prabhu <roopa@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/route.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -5453,7 +5453,11 @@ static int ip6_route_multipath_del(struc
+                       nla = nla_find(attrs, attrlen, RTA_GATEWAY);
+                       if (nla) {
+-                              nla_memcpy(&r_cfg.fc_gateway, nla, 16);
++                              err = fib6_gw_from_attr(&r_cfg.fc_gateway, nla,
++                                                      extack);
++                              if (err)
++                                      return err;
++
+                               r_cfg.fc_flags |= RTF_GATEWAY;
+                       }
+               }
diff --git a/queue-5.15/lwtunnel-validate-rta_encap_type-attribute-length.patch b/queue-5.15/lwtunnel-validate-rta_encap_type-attribute-length.patch
new file mode 100644 (file)
index 0000000..5f30c1d
--- /dev/null
@@ -0,0 +1,67 @@
+From 8bda81a4d400cf8a72e554012f0d8c45e07a3904 Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@kernel.org>
+Date: Thu, 30 Dec 2021 17:36:35 -0700
+Subject: lwtunnel: Validate RTA_ENCAP_TYPE attribute length
+
+From: David Ahern <dsahern@kernel.org>
+
+commit 8bda81a4d400cf8a72e554012f0d8c45e07a3904 upstream.
+
+lwtunnel_valid_encap_type_attr is used to validate encap attributes
+within a multipath route. Add length validation checking to the type.
+
+lwtunnel_valid_encap_type_attr is called converting attributes to
+fib{6,}_config struct which means it is used before fib_get_nhs,
+ip6_route_multipath_add, and ip6_route_multipath_del - other
+locations that use rtnh_ok and then nla_get_u16 on RTA_ENCAP_TYPE
+attribute.
+
+Fixes: 9ed59592e3e3 ("lwtunnel: fix autoload of lwt modules")
+
+Signed-off-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/lwtunnel.c      |    4 ++++
+ net/ipv4/fib_semantics.c |    3 +++
+ net/ipv6/route.c         |    4 ++++
+ 3 files changed, 11 insertions(+)
+
+--- a/net/core/lwtunnel.c
++++ b/net/core/lwtunnel.c
+@@ -197,6 +197,10 @@ int lwtunnel_valid_encap_type_attr(struc
+                       nla_entype = nla_find(attrs, attrlen, RTA_ENCAP_TYPE);
+                       if (nla_entype) {
++                              if (nla_len(nla_entype) < sizeof(u16)) {
++                                      NL_SET_ERR_MSG(extack, "Invalid RTA_ENCAP_TYPE");
++                                      return -EINVAL;
++                              }
+                               encap_type = nla_get_u16(nla_entype);
+                               if (lwtunnel_valid_encap_type(encap_type,
+--- a/net/ipv4/fib_semantics.c
++++ b/net/ipv4/fib_semantics.c
+@@ -740,6 +740,9 @@ static int fib_get_nhs(struct fib_info *
+                       }
+                       fib_cfg.fc_encap = nla_find(attrs, attrlen, RTA_ENCAP);
++                      /* RTA_ENCAP_TYPE length checked in
++                       * lwtunnel_valid_encap_type_attr
++                       */
+                       nla = nla_find(attrs, attrlen, RTA_ENCAP_TYPE);
+                       if (nla)
+                               fib_cfg.fc_encap_type = nla_get_u16(nla);
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -5287,6 +5287,10 @@ static int ip6_route_multipath_add(struc
+                               r_cfg.fc_flags |= RTF_GATEWAY;
+                       }
+                       r_cfg.fc_encap = nla_find(attrs, attrlen, RTA_ENCAP);
++
++                      /* RTA_ENCAP_TYPE length checked in
++                       * lwtunnel_valid_encap_type_attr
++                       */
+                       nla = nla_find(attrs, attrlen, RTA_ENCAP_TYPE);
+                       if (nla)
+                               r_cfg.fc_encap_type = nla_get_u16(nla);
diff --git a/queue-5.15/net-ena-fix-error-handling-when-calculating-max-io-queues-number.patch b/queue-5.15/net-ena-fix-error-handling-when-calculating-max-io-queues-number.patch
new file mode 100644 (file)
index 0000000..1df963c
--- /dev/null
@@ -0,0 +1,51 @@
+From 5055dc0348b8b7c168e3296044bccd724e1ae6cd Mon Sep 17 00:00:00 2001
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Sun, 2 Jan 2022 07:37:28 +0000
+Subject: net: ena: Fix error handling when calculating max IO queues number
+
+From: Arthur Kiyanovski <akiyano@amazon.com>
+
+commit 5055dc0348b8b7c168e3296044bccd724e1ae6cd upstream.
+
+The role of ena_calc_max_io_queue_num() is to return the number
+of queues supported by the device, which means the return value
+should be >=0.
+
+The function that calls ena_calc_max_io_queue_num(), checks
+the return value. If it is 0, it means the device reported
+it supports 0 IO queues. This case is considered an error
+and is handled by the calling function accordingly.
+
+However the current implementation of ena_calc_max_io_queue_num()
+is wrong, since when it detects the device supports 0 IO queues,
+it returns -EFAULT.
+
+In such a case the calling function doesn't detect the error,
+and therefore doesn't handle it.
+
+This commit changes ena_calc_max_io_queue_num() to return 0
+in case the device reported it supports 0 queues, allowing the
+calling function to properly handle the error case.
+
+Fixes: 736ce3f414cc ("net: ena: make ethtool -l show correct max number of queues")
+Signed-off-by: Shay Agroskin <shayagr@amazon.com>
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c |    4 ----
+ 1 file changed, 4 deletions(-)
+
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -4026,10 +4026,6 @@ static u32 ena_calc_max_io_queue_num(str
+       max_num_io_queues = min_t(u32, max_num_io_queues, io_tx_cq_num);
+       /* 1 IRQ for mgmnt and 1 IRQs for each IO direction */
+       max_num_io_queues = min_t(u32, max_num_io_queues, pci_msix_vec_count(pdev) - 1);
+-      if (unlikely(!max_num_io_queues)) {
+-              dev_err(&pdev->dev, "The device doesn't have io queues\n");
+-              return -EFAULT;
+-      }
+       return max_num_io_queues;
+ }
diff --git a/queue-5.15/net-ena-fix-undefined-state-when-tx-request-id-is-out-of-bounds.patch b/queue-5.15/net-ena-fix-undefined-state-when-tx-request-id-is-out-of-bounds.patch
new file mode 100644 (file)
index 0000000..753aef5
--- /dev/null
@@ -0,0 +1,103 @@
+From c255a34e02efb1393d23ffb205ba1a11320aeffb Mon Sep 17 00:00:00 2001
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Sun, 2 Jan 2022 07:37:26 +0000
+Subject: net: ena: Fix undefined state when tx request id is out of bounds
+
+From: Arthur Kiyanovski <akiyano@amazon.com>
+
+commit c255a34e02efb1393d23ffb205ba1a11320aeffb upstream.
+
+ena_com_tx_comp_req_id_get() checks the req_id of a received completion,
+and if it is out of bounds returns -EINVAL. This is a sign that
+something is wrong with the device and it needs to be reset.
+
+The current code does not reset the device in this case, which leaves
+the driver in an undefined state, where this completion is not properly
+handled.
+
+This commit adds a call to handle_invalid_req_id() in ena_clean_tx_irq()
+and ena_clean_xdp_irq() which resets the device to fix the issue.
+
+This commit also removes unnecessary request id checks from
+validate_tx_req_id() and validate_xdp_req_id(). This check is unneeded
+because it was already performed in ena_com_tx_comp_req_id_get(), which
+is called right before these functions.
+
+Fixes: 548c4940b9f1 ("net: ena: Implement XDP_TX action")
+Signed-off-by: Shay Agroskin <shayagr@amazon.com>
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c |   34 +++++++++++++++------------
+ 1 file changed, 20 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -1288,26 +1288,22 @@ static int handle_invalid_req_id(struct
+ static int validate_tx_req_id(struct ena_ring *tx_ring, u16 req_id)
+ {
+-      struct ena_tx_buffer *tx_info = NULL;
++      struct ena_tx_buffer *tx_info;
+-      if (likely(req_id < tx_ring->ring_size)) {
+-              tx_info = &tx_ring->tx_buffer_info[req_id];
+-              if (likely(tx_info->skb))
+-                      return 0;
+-      }
++      tx_info = &tx_ring->tx_buffer_info[req_id];
++      if (likely(tx_info->skb))
++              return 0;
+       return handle_invalid_req_id(tx_ring, req_id, tx_info, false);
+ }
+ static int validate_xdp_req_id(struct ena_ring *xdp_ring, u16 req_id)
+ {
+-      struct ena_tx_buffer *tx_info = NULL;
++      struct ena_tx_buffer *tx_info;
+-      if (likely(req_id < xdp_ring->ring_size)) {
+-              tx_info = &xdp_ring->tx_buffer_info[req_id];
+-              if (likely(tx_info->xdpf))
+-                      return 0;
+-      }
++      tx_info = &xdp_ring->tx_buffer_info[req_id];
++      if (likely(tx_info->xdpf))
++              return 0;
+       return handle_invalid_req_id(xdp_ring, req_id, tx_info, true);
+ }
+@@ -1332,9 +1328,14 @@ static int ena_clean_tx_irq(struct ena_r
+               rc = ena_com_tx_comp_req_id_get(tx_ring->ena_com_io_cq,
+                                               &req_id);
+-              if (rc)
++              if (rc) {
++                      if (unlikely(rc == -EINVAL))
++                              handle_invalid_req_id(tx_ring, req_id, NULL,
++                                                    false);
+                       break;
++              }
++              /* validate that the request id points to a valid skb */
+               rc = validate_tx_req_id(tx_ring, req_id);
+               if (rc)
+                       break;
+@@ -1896,9 +1897,14 @@ static int ena_clean_xdp_irq(struct ena_
+               rc = ena_com_tx_comp_req_id_get(xdp_ring->ena_com_io_cq,
+                                               &req_id);
+-              if (rc)
++              if (rc) {
++                      if (unlikely(rc == -EINVAL))
++                              handle_invalid_req_id(xdp_ring, req_id, NULL,
++                                                    true);
+                       break;
++              }
++              /* validate that the request id points to a valid xdp_frame */
+               rc = validate_xdp_req_id(xdp_ring, req_id);
+               if (rc)
+                       break;
diff --git a/queue-5.15/net-ena-fix-wrong-rx-request-id-by-resetting-device.patch b/queue-5.15/net-ena-fix-wrong-rx-request-id-by-resetting-device.patch
new file mode 100644 (file)
index 0000000..a4edd25
--- /dev/null
@@ -0,0 +1,50 @@
+From cb3d4f98f0b26eafa0b913ac3716e4714254a747 Mon Sep 17 00:00:00 2001
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Sun, 2 Jan 2022 07:37:27 +0000
+Subject: net: ena: Fix wrong rx request id by resetting device
+
+From: Arthur Kiyanovski <akiyano@amazon.com>
+
+commit cb3d4f98f0b26eafa0b913ac3716e4714254a747 upstream.
+
+A wrong request id received from the device is a sign that
+something is wrong with it, therefore trigger a device reset.
+
+Also add some debug info to the "Page is NULL" print to make
+it easier to debug.
+
+Fixes: 1738cd3ed342 ("net: ena: Add a driver for Amazon Elastic Network Adapters (ENA)")
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -1428,6 +1428,7 @@ static struct sk_buff *ena_rx_skb(struct
+                                 u16 *next_to_clean)
+ {
+       struct ena_rx_buffer *rx_info;
++      struct ena_adapter *adapter;
+       u16 len, req_id, buf = 0;
+       struct sk_buff *skb;
+       void *page_addr;
+@@ -1440,8 +1441,14 @@ static struct sk_buff *ena_rx_skb(struct
+       rx_info = &rx_ring->rx_buffer_info[req_id];
+       if (unlikely(!rx_info->page)) {
+-              netif_err(rx_ring->adapter, rx_err, rx_ring->netdev,
+-                        "Page is NULL\n");
++              adapter = rx_ring->adapter;
++              netif_err(adapter, rx_err, rx_ring->netdev,
++                        "Page is NULL. qid %u req_id %u\n", rx_ring->qid, req_id);
++              ena_increase_stat(&rx_ring->rx_stats.bad_req_id, 1, &rx_ring->syncp);
++              adapter->reset_reason = ENA_REGS_RESET_INV_RX_REQ_ID;
++              /* Make sure reset reason is set before triggering the reset */
++              smp_mb__before_atomic();
++              set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
+               return NULL;
+       }
diff --git a/queue-5.15/sch_qfq-prevent-shift-out-of-bounds-in-qfq_init_qdisc.patch b/queue-5.15/sch_qfq-prevent-shift-out-of-bounds-in-qfq_init_qdisc.patch
new file mode 100644 (file)
index 0000000..0f83d2b
--- /dev/null
@@ -0,0 +1,65 @@
+From 7d18a07897d07495ee140dd319b0e9265c0f68ba Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Tue, 4 Jan 2022 01:45:08 -0800
+Subject: sch_qfq: prevent shift-out-of-bounds in qfq_init_qdisc
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit 7d18a07897d07495ee140dd319b0e9265c0f68ba upstream.
+
+tx_queue_len can be set to ~0U, we need to be more
+careful about overflows.
+
+__fls(0) is undefined, as this report shows:
+
+UBSAN: shift-out-of-bounds in net/sched/sch_qfq.c:1430:24
+shift exponent 51770272 is too large for 32-bit type 'int'
+CPU: 0 PID: 25574 Comm: syz-executor.0 Not tainted 5.16.0-rc7-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0x201/0x2d8 lib/dump_stack.c:106
+ ubsan_epilogue lib/ubsan.c:151 [inline]
+ __ubsan_handle_shift_out_of_bounds+0x494/0x530 lib/ubsan.c:330
+ qfq_init_qdisc+0x43f/0x450 net/sched/sch_qfq.c:1430
+ qdisc_create+0x895/0x1430 net/sched/sch_api.c:1253
+ tc_modify_qdisc+0x9d9/0x1e20 net/sched/sch_api.c:1660
+ rtnetlink_rcv_msg+0x934/0xe60 net/core/rtnetlink.c:5571
+ netlink_rcv_skb+0x200/0x470 net/netlink/af_netlink.c:2496
+ netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline]
+ netlink_unicast+0x814/0x9f0 net/netlink/af_netlink.c:1345
+ netlink_sendmsg+0xaea/0xe60 net/netlink/af_netlink.c:1921
+ sock_sendmsg_nosec net/socket.c:704 [inline]
+ sock_sendmsg net/socket.c:724 [inline]
+ ____sys_sendmsg+0x5b9/0x910 net/socket.c:2409
+ ___sys_sendmsg net/socket.c:2463 [inline]
+ __sys_sendmsg+0x280/0x370 net/socket.c:2492
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x44/0xd0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+Fixes: 462dbc9101ac ("pkt_sched: QFQ Plus: fair-queueing service at DRR cost")
+Signed-off-by: Eric Dumazet <edumazet@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>
+---
+ net/sched/sch_qfq.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/net/sched/sch_qfq.c
++++ b/net/sched/sch_qfq.c
+@@ -1422,10 +1422,8 @@ static int qfq_init_qdisc(struct Qdisc *
+       if (err < 0)
+               return err;
+-      if (qdisc_dev(sch)->tx_queue_len + 1 > QFQ_MAX_AGG_CLASSES)
+-              max_classes = QFQ_MAX_AGG_CLASSES;
+-      else
+-              max_classes = qdisc_dev(sch)->tx_queue_len + 1;
++      max_classes = min_t(u64, (u64)qdisc_dev(sch)->tx_queue_len + 1,
++                          QFQ_MAX_AGG_CLASSES);
+       /* max_cl_shift = floor(log_2(max_classes)) */
+       max_cl_shift = __fls(max_classes);
+       q->max_agg_classes = 1<<max_cl_shift;
diff --git a/queue-5.15/sctp-hold-endpoint-before-calling-cb-in-sctp_transport_lookup_process.patch b/queue-5.15/sctp-hold-endpoint-before-calling-cb-in-sctp_transport_lookup_process.patch
new file mode 100644 (file)
index 0000000..892c8e4
--- /dev/null
@@ -0,0 +1,172 @@
+From f9d31c4cf4c11ff10317f038b9c6f7c3bda6cdd4 Mon Sep 17 00:00:00 2001
+From: Xin Long <lucien.xin@gmail.com>
+Date: Fri, 31 Dec 2021 18:37:37 -0500
+Subject: sctp: hold endpoint before calling cb in sctp_transport_lookup_process
+
+From: Xin Long <lucien.xin@gmail.com>
+
+commit f9d31c4cf4c11ff10317f038b9c6f7c3bda6cdd4 upstream.
+
+The same fix in commit 5ec7d18d1813 ("sctp: use call_rcu to free endpoint")
+is also needed for dumping one asoc and sock after the lookup.
+
+Fixes: 86fdb3448cc1 ("sctp: ensure ep is not destroyed before doing the dump")
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/sctp/sctp.h |    3 +--
+ net/sctp/diag.c         |   48 ++++++++++++++++++++++--------------------------
+ net/sctp/socket.c       |   22 +++++++++++++++-------
+ 3 files changed, 38 insertions(+), 35 deletions(-)
+
+--- a/include/net/sctp/sctp.h
++++ b/include/net/sctp/sctp.h
+@@ -112,8 +112,7 @@ struct sctp_transport *sctp_transport_ge
+                       struct rhashtable_iter *iter);
+ struct sctp_transport *sctp_transport_get_idx(struct net *net,
+                       struct rhashtable_iter *iter, int pos);
+-int sctp_transport_lookup_process(int (*cb)(struct sctp_transport *, void *),
+-                                struct net *net,
++int sctp_transport_lookup_process(sctp_callback_t cb, struct net *net,
+                                 const union sctp_addr *laddr,
+                                 const union sctp_addr *paddr, void *p);
+ int sctp_transport_traverse_process(sctp_callback_t cb, sctp_callback_t cb_done,
+--- a/net/sctp/diag.c
++++ b/net/sctp/diag.c
+@@ -245,48 +245,44 @@ static size_t inet_assoc_attr_size(struc
+               + 64;
+ }
+-static int sctp_tsp_dump_one(struct sctp_transport *tsp, void *p)
++static int sctp_sock_dump_one(struct sctp_endpoint *ep, struct sctp_transport *tsp, void *p)
+ {
+       struct sctp_association *assoc = tsp->asoc;
+-      struct sock *sk = tsp->asoc->base.sk;
+       struct sctp_comm_param *commp = p;
+-      struct sk_buff *in_skb = commp->skb;
++      struct sock *sk = ep->base.sk;
+       const struct inet_diag_req_v2 *req = commp->r;
+-      const struct nlmsghdr *nlh = commp->nlh;
+-      struct net *net = sock_net(in_skb->sk);
++      struct sk_buff *skb = commp->skb;
+       struct sk_buff *rep;
+       int err;
+       err = sock_diag_check_cookie(sk, req->id.idiag_cookie);
+       if (err)
+-              goto out;
++              return err;
+-      err = -ENOMEM;
+       rep = nlmsg_new(inet_assoc_attr_size(assoc), GFP_KERNEL);
+       if (!rep)
+-              goto out;
++              return -ENOMEM;
+       lock_sock(sk);
+-      if (sk != assoc->base.sk) {
+-              release_sock(sk);
+-              sk = assoc->base.sk;
+-              lock_sock(sk);
+-      }
+-      err = inet_sctp_diag_fill(sk, assoc, rep, req,
+-                                sk_user_ns(NETLINK_CB(in_skb).sk),
+-                                NETLINK_CB(in_skb).portid,
+-                                nlh->nlmsg_seq, 0, nlh,
+-                                commp->net_admin);
+-      release_sock(sk);
++      if (ep != assoc->ep) {
++              err = -EAGAIN;
++              goto out;
++      }
++
++      err = inet_sctp_diag_fill(sk, assoc, rep, req, sk_user_ns(NETLINK_CB(skb).sk),
++                                NETLINK_CB(skb).portid, commp->nlh->nlmsg_seq, 0,
++                                commp->nlh, commp->net_admin);
+       if (err < 0) {
+               WARN_ON(err == -EMSGSIZE);
+-              kfree_skb(rep);
+               goto out;
+       }
++      release_sock(sk);
+-      err = nlmsg_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid);
++      return nlmsg_unicast(sock_net(skb->sk)->diag_nlsk, rep, NETLINK_CB(skb).portid);
+ out:
++      release_sock(sk);
++      kfree_skb(rep);
+       return err;
+ }
+@@ -429,15 +425,15 @@ static void sctp_diag_get_info(struct so
+ static int sctp_diag_dump_one(struct netlink_callback *cb,
+                             const struct inet_diag_req_v2 *req)
+ {
+-      struct sk_buff *in_skb = cb->skb;
+-      struct net *net = sock_net(in_skb->sk);
++      struct sk_buff *skb = cb->skb;
++      struct net *net = sock_net(skb->sk);
+       const struct nlmsghdr *nlh = cb->nlh;
+       union sctp_addr laddr, paddr;
+       struct sctp_comm_param commp = {
+-              .skb = in_skb,
++              .skb = skb,
+               .r = req,
+               .nlh = nlh,
+-              .net_admin = netlink_net_capable(in_skb, CAP_NET_ADMIN),
++              .net_admin = netlink_net_capable(skb, CAP_NET_ADMIN),
+       };
+       if (req->sdiag_family == AF_INET) {
+@@ -460,7 +456,7 @@ static int sctp_diag_dump_one(struct net
+               paddr.v6.sin6_family = AF_INET6;
+       }
+-      return sctp_transport_lookup_process(sctp_tsp_dump_one,
++      return sctp_transport_lookup_process(sctp_sock_dump_one,
+                                            net, &laddr, &paddr, &commp);
+ }
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -5317,23 +5317,31 @@ int sctp_for_each_endpoint(int (*cb)(str
+ }
+ EXPORT_SYMBOL_GPL(sctp_for_each_endpoint);
+-int sctp_transport_lookup_process(int (*cb)(struct sctp_transport *, void *),
+-                                struct net *net,
++int sctp_transport_lookup_process(sctp_callback_t cb, struct net *net,
+                                 const union sctp_addr *laddr,
+                                 const union sctp_addr *paddr, void *p)
+ {
+       struct sctp_transport *transport;
+-      int err;
++      struct sctp_endpoint *ep;
++      int err = -ENOENT;
+       rcu_read_lock();
+       transport = sctp_addrs_lookup_transport(net, laddr, paddr);
++      if (!transport) {
++              rcu_read_unlock();
++              return err;
++      }
++      ep = transport->asoc->ep;
++      if (!sctp_endpoint_hold(ep)) { /* asoc can be peeled off */
++              sctp_transport_put(transport);
++              rcu_read_unlock();
++              return err;
++      }
+       rcu_read_unlock();
+-      if (!transport)
+-              return -ENOENT;
+-      err = cb(transport, p);
++      err = cb(ep, transport, p);
++      sctp_endpoint_put(ep);
+       sctp_transport_put(transport);
+-
+       return err;
+ }
+ EXPORT_SYMBOL_GPL(sctp_transport_lookup_process);
diff --git a/queue-5.15/selftests-net-udpgro_fwd.sh-explicitly-checking-the-available-ping-feature.patch b/queue-5.15/selftests-net-udpgro_fwd.sh-explicitly-checking-the-available-ping-feature.patch
new file mode 100644 (file)
index 0000000..bfd3fde
--- /dev/null
@@ -0,0 +1,34 @@
+From 5e75d0b215b868337e7a193f28a543ec00e858b1 Mon Sep 17 00:00:00 2001
+From: Jianguo Wu <wujianguo@chinatelecom.cn>
+Date: Fri, 31 Dec 2021 10:01:08 +0800
+Subject: selftests: net: udpgro_fwd.sh: explicitly checking the available ping feature
+
+From: Jianguo Wu <wujianguo@chinatelecom.cn>
+
+commit 5e75d0b215b868337e7a193f28a543ec00e858b1 upstream.
+
+As Paolo pointed out, the result of ping IPv6 address depends on
+the running distro. So explicitly checking the available ping feature,
+as e.g. do the bareudp.sh self-tests.
+
+Fixes: 8b3170e07539 ("selftests: net: using ping6 for IPv6 in udpgro_fwd.sh")
+Signed-off-by: Jianguo Wu <wujianguo@chinatelecom.cn>
+Link: https://lore.kernel.org/r/825ee22b-4245-dbf7-d2f7-a230770d6e21@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/net/udpgro_fwd.sh |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/tools/testing/selftests/net/udpgro_fwd.sh
++++ b/tools/testing/selftests/net/udpgro_fwd.sh
+@@ -193,7 +193,8 @@ for family in 4 6; do
+               SUFFIX="64 nodad"
+               VXDEV=vxlan6
+               IPT=ip6tables
+-              PING="ping6"
++              # Use ping6 on systems where ping doesn't handle IPv6
++              ping -w 1 -c 1 ::1 > /dev/null 2>&1 || PING="ping6"
+       fi
+       echo "IPv$family"
index 74f96d40ae89d92dab640d6bdb306a20b88edfd0..4a919f995ce4c7b4e71703328738c923a8df51c7 100644 (file)
@@ -12,3 +12,20 @@ netrom-fix-copying-in-user-data-in-nr_setsockopt.patch
 rdma-uverbs-check-for-null-return-of-kmalloc_array.patch
 mac80211-initialize-variable-have_higher_than_11mbit.patch
 mac80211-mesh-embedd-mesh_paths-and-mpp_paths-into-ieee80211_if_mesh.patch
+sfc-the-rx-page_ring-is-optional.patch
+i40e-fix-use-after-free-in-i40e_sync_filters_subtask.patch
+i40e-fix-for-displaying-message-regarding-nvm-version.patch
+i40e-fix-incorrect-netdev-s-real-number-of-rx-tx-queues.patch
+ftrace-samples-add-missing-prototypes-direct-functions.patch
+ipv4-check-attribute-length-for-rta_gateway-in-multipath-route.patch
+ipv4-check-attribute-length-for-rta_flow-in-multipath-route.patch
+ipv6-check-attribute-length-for-rta_gateway-in-multipath-route.patch
+ipv6-check-attribute-length-for-rta_gateway-when-deleting-multipath-route.patch
+lwtunnel-validate-rta_encap_type-attribute-length.patch
+selftests-net-udpgro_fwd.sh-explicitly-checking-the-available-ping-feature.patch
+sctp-hold-endpoint-before-calling-cb-in-sctp_transport_lookup_process.patch
+batman-adv-mcast-don-t-send-link-local-multicast-to-mcast-routers.patch
+sch_qfq-prevent-shift-out-of-bounds-in-qfq_init_qdisc.patch
+net-ena-fix-undefined-state-when-tx-request-id-is-out-of-bounds.patch
+net-ena-fix-wrong-rx-request-id-by-resetting-device.patch
+net-ena-fix-error-handling-when-calculating-max-io-queues-number.patch
diff --git a/queue-5.15/sfc-the-rx-page_ring-is-optional.patch b/queue-5.15/sfc-the-rx-page_ring-is-optional.patch
new file mode 100644 (file)
index 0000000..4be065f
--- /dev/null
@@ -0,0 +1,67 @@
+From 1d5a474240407c38ca8c7484a656ee39f585399c Mon Sep 17 00:00:00 2001
+From: Martin Habets <habetsm.xilinx@gmail.com>
+Date: Sun, 2 Jan 2022 08:41:22 +0000
+Subject: sfc: The RX page_ring is optional
+
+From: Martin Habets <habetsm.xilinx@gmail.com>
+
+commit 1d5a474240407c38ca8c7484a656ee39f585399c upstream.
+
+The RX page_ring is an optional feature that improves
+performance. When allocation fails the driver can still
+function, but possibly with a lower bandwidth.
+Guard against dereferencing a NULL page_ring.
+
+Fixes: 2768935a4660 ("sfc: reuse pages to avoid DMA mapping/unmapping costs")
+Signed-off-by: Martin Habets <habetsm.xilinx@gmail.com>
+Reported-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Link: https://lore.kernel.org/r/164111288276.5798.10330502993729113868.stgit@palantir17.mph.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/sfc/falcon/rx.c |    5 +++++
+ drivers/net/ethernet/sfc/rx_common.c |    5 +++++
+ 2 files changed, 10 insertions(+)
+
+--- a/drivers/net/ethernet/sfc/falcon/rx.c
++++ b/drivers/net/ethernet/sfc/falcon/rx.c
+@@ -110,6 +110,8 @@ static struct page *ef4_reuse_page(struc
+       struct ef4_rx_page_state *state;
+       unsigned index;
++      if (unlikely(!rx_queue->page_ring))
++              return NULL;
+       index = rx_queue->page_remove & rx_queue->page_ptr_mask;
+       page = rx_queue->page_ring[index];
+       if (page == NULL)
+@@ -293,6 +295,9 @@ static void ef4_recycle_rx_pages(struct
+ {
+       struct ef4_rx_queue *rx_queue = ef4_channel_get_rx_queue(channel);
++      if (unlikely(!rx_queue->page_ring))
++              return;
++
+       do {
+               ef4_recycle_rx_page(channel, rx_buf);
+               rx_buf = ef4_rx_buf_next(rx_queue, rx_buf);
+--- a/drivers/net/ethernet/sfc/rx_common.c
++++ b/drivers/net/ethernet/sfc/rx_common.c
+@@ -45,6 +45,8 @@ static struct page *efx_reuse_page(struc
+       unsigned int index;
+       struct page *page;
++      if (unlikely(!rx_queue->page_ring))
++              return NULL;
+       index = rx_queue->page_remove & rx_queue->page_ptr_mask;
+       page = rx_queue->page_ring[index];
+       if (page == NULL)
+@@ -114,6 +116,9 @@ void efx_recycle_rx_pages(struct efx_cha
+ {
+       struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel);
++      if (unlikely(!rx_queue->page_ring))
++              return;
++
+       do {
+               efx_recycle_rx_page(channel, rx_buf);
+               rx_buf = efx_rx_buf_next(rx_queue, rx_buf);