kernel: backport MTK ethernet/WLAN offload fixes
authorFelix Fietkau <nbd@nbd.name>
Tue, 20 Sep 2022 09:32:51 +0000 (11:32 +0200)
committerFelix Fietkau <nbd@nbd.name>
Tue, 20 Sep 2022 10:08:26 +0000 (12:08 +0200)
Fixes issues with offloading to WED, especially with VLAN bridges involved

Signed-off-by: Felix Fietkau <nbd@nbd.name>
target/linux/generic/backport-5.15/711-v6.0-01-net-ethernet-mtk_eth_soc-fix-off-by-one-check-of-ARR.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/711-v6.0-02-net-ethernet-mtk_ppe-fix-possible-NULL-pointer-deref.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/711-v6.0-03-net-ethernet-mtk-ppe-fix-traffic-offload-with-bridge.patch [new file with mode: 0644]

diff --git a/target/linux/generic/backport-5.15/711-v6.0-01-net-ethernet-mtk_eth_soc-fix-off-by-one-check-of-ARR.patch b/target/linux/generic/backport-5.15/711-v6.0-01-net-ethernet-mtk_eth_soc-fix-off-by-one-check-of-ARR.patch
new file mode 100644 (file)
index 0000000..0de8ab4
--- /dev/null
@@ -0,0 +1,31 @@
+From: Tom Rix <trix@redhat.com>
+Date: Sat, 16 Jul 2022 17:46:54 -0400
+Subject: [PATCH] net: ethernet: mtk_eth_soc: fix off by one check of
+ ARRAY_SIZE
+
+In mtk_wed_tx_ring_setup(.., int idx, ..), idx is used as an index here
+  struct mtk_wed_ring *ring = &dev->tx_ring[idx];
+
+The bounds of idx are checked here
+  BUG_ON(idx > ARRAY_SIZE(dev->tx_ring));
+
+If idx is the size of the array, it will pass this check and overflow.
+So change the check to >= .
+
+Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)")
+Signed-off-by: Tom Rix <trix@redhat.com>
+Link: https://lore.kernel.org/r/20220716214654.1540240-1-trix@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -651,7 +651,7 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev
+        * WDMA RX.
+        */
+-      BUG_ON(idx > ARRAY_SIZE(dev->tx_ring));
++      BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring));
+       if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE))
+               return -ENOMEM;
diff --git a/target/linux/generic/backport-5.15/711-v6.0-02-net-ethernet-mtk_ppe-fix-possible-NULL-pointer-deref.patch b/target/linux/generic/backport-5.15/711-v6.0-02-net-ethernet-mtk_ppe-fix-possible-NULL-pointer-deref.patch
new file mode 100644 (file)
index 0000000..fc6e246
--- /dev/null
@@ -0,0 +1,27 @@
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Mon, 18 Jul 2022 11:51:53 +0200
+Subject: [PATCH] net: ethernet: mtk_ppe: fix possible NULL pointer dereference
+ in mtk_flow_get_wdma_info
+
+odev pointer can be NULL in mtk_flow_offload_replace routine according
+to the flower action rules. Fix possible NULL pointer dereference in
+mtk_flow_get_wdma_info.
+
+Fixes: a333215e10cb5 ("net: ethernet: mtk_eth_soc: implement flow offloading to WED devices")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://lore.kernel.org/r/4e1685bc4976e21e364055f6bee86261f8f9ee93.1658137753.git.lorenzo@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+@@ -93,6 +93,9 @@ mtk_flow_get_wdma_info(struct net_device
+       };
+       struct net_device_path path = {};
++      if (!ctx.dev)
++              return -ENODEV;
++
+       memcpy(ctx.daddr, addr, sizeof(ctx.daddr));
+       if (!IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED))
diff --git a/target/linux/generic/backport-5.15/711-v6.0-03-net-ethernet-mtk-ppe-fix-traffic-offload-with-bridge.patch b/target/linux/generic/backport-5.15/711-v6.0-03-net-ethernet-mtk-ppe-fix-traffic-offload-with-bridge.patch
new file mode 100644 (file)
index 0000000..c072015
--- /dev/null
@@ -0,0 +1,64 @@
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Fri, 22 Jul 2022 09:06:19 +0200
+Subject: [PATCH] net: ethernet: mtk-ppe: fix traffic offload with bridged wlan
+
+A typical flow offload scenario for OpenWrt users is routed traffic
+received by the wan interface that is redirected to a wlan device
+belonging to the lan bridge. Current implementation fails to
+fill wdma offload info in mtk_flow_get_wdma_info() since odev device is
+the local bridge. Fix the issue running dev_fill_forward_path routine in
+mtk_flow_get_wdma_info in order to identify the wlan device.
+
+Tested-by: Paolo Valerio <pvalerio@redhat.com>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+@@ -88,32 +88,28 @@ mtk_flow_offload_mangle_eth(const struct
+ static int
+ mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_info *info)
+ {
+-      struct net_device_path_ctx ctx = {
+-              .dev = dev,
+-      };
+-      struct net_device_path path = {};
++      struct net_device_path_stack stack;
++      struct net_device_path *path;
++      int err;
+-      if (!ctx.dev)
++      if (!dev)
+               return -ENODEV;
+-      memcpy(ctx.daddr, addr, sizeof(ctx.daddr));
+-
+       if (!IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED))
+               return -1;
+-      if (!dev->netdev_ops->ndo_fill_forward_path)
+-              return -1;
+-
+-      if (dev->netdev_ops->ndo_fill_forward_path(&ctx, &path))
+-              return -1;
++      err = dev_fill_forward_path(dev, addr, &stack);
++      if (err)
++              return err;
+-      if (path.type != DEV_PATH_MTK_WDMA)
++      path = &stack.path[stack.num_paths - 1];
++      if (path->type != DEV_PATH_MTK_WDMA)
+               return -1;
+-      info->wdma_idx = path.mtk_wdma.wdma_idx;
+-      info->queue = path.mtk_wdma.queue;
+-      info->bss = path.mtk_wdma.bss;
+-      info->wcid = path.mtk_wdma.wcid;
++      info->wdma_idx = path->mtk_wdma.wdma_idx;
++      info->queue = path->mtk_wdma.queue;
++      info->bss = path->mtk_wdma.bss;
++      info->wcid = path->mtk_wdma.wcid;
+       return 0;
+ }