aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/pending-5.15
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2023-03-20 18:06:23 +0100
committerFelix Fietkau <nbd@nbd.name>2023-03-20 21:28:19 +0100
commit1d8baafc438d9beff25e04550b1f894aab771bfe (patch)
tree43eeb9176b9738f2c35f551e3cab2f3cdcde5610 /target/linux/generic/pending-5.15
parent82ce3403844ae53583eefbd941d579c98337bd35 (diff)
downloadupstream-1d8baafc438d9beff25e04550b1f894aab771bfe.tar.gz
upstream-1d8baafc438d9beff25e04550b1f894aab771bfe.tar.bz2
upstream-1d8baafc438d9beff25e04550b1f894aab771bfe.zip
kernel: move mediatek flow offload refcount fix and fix a logic error
Move it to pending, since it wasn't actually accepted upstream yet. Fixes potential issues when doing offload between multiple MACs. Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'target/linux/generic/pending-5.15')
-rw-r--r--target/linux/generic/pending-5.15/735-net-ethernet-mtk_eth_soc-fix-flow_offload-related-re.patch61
1 files changed, 61 insertions, 0 deletions
diff --git a/target/linux/generic/pending-5.15/735-net-ethernet-mtk_eth_soc-fix-flow_offload-related-re.patch b/target/linux/generic/pending-5.15/735-net-ethernet-mtk_eth_soc-fix-flow_offload-related-re.patch
new file mode 100644
index 0000000000..acbdec2159
--- /dev/null
+++ b/target/linux/generic/pending-5.15/735-net-ethernet-mtk_eth_soc-fix-flow_offload-related-re.patch
@@ -0,0 +1,61 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Mon, 20 Mar 2023 15:49:15 +0100
+Subject: [PATCH] net: ethernet: mtk_eth_soc: fix flow_offload related refcount
+ bug
+
+Since we call flow_block_cb_decref on FLOW_BLOCK_UNBIND, we need to call
+flow_block_cb_incref unconditionally, even for a newly allocated cb.
+Fixes a use-after-free bug. Also fix the accidentally inverted refcount
+check on unbind.
+
+Fixes: 502e84e2382d ("net: ethernet: mtk_eth_soc: add flow offloading support")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+@@ -561,6 +561,7 @@ mtk_eth_setup_tc_block(struct net_device
+ struct mtk_eth *eth = mac->hw;
+ static LIST_HEAD(block_cb_list);
+ struct flow_block_cb *block_cb;
++ bool register_block = false;
+ flow_setup_cb_t *cb;
+
+ if (!eth->soc->offload_version)
+@@ -575,23 +576,27 @@ mtk_eth_setup_tc_block(struct net_device
+ switch (f->command) {
+ case FLOW_BLOCK_BIND:
+ block_cb = flow_block_cb_lookup(f->block, cb, dev);
+- if (block_cb) {
+- flow_block_cb_incref(block_cb);
+- return 0;
++ if (!block_cb) {
++ block_cb = flow_block_cb_alloc(cb, dev, dev, NULL);
++ if (IS_ERR(block_cb))
++ return PTR_ERR(block_cb);
++
++ register_block = true;
+ }
+- block_cb = flow_block_cb_alloc(cb, dev, dev, NULL);
+- if (IS_ERR(block_cb))
+- return PTR_ERR(block_cb);
+
+- flow_block_cb_add(block_cb, f);
+- list_add_tail(&block_cb->driver_list, &block_cb_list);
++ flow_block_cb_incref(block_cb);
++
++ if (register_block) {
++ flow_block_cb_add(block_cb, f);
++ list_add_tail(&block_cb->driver_list, &block_cb_list);
++ }
+ return 0;
+ case FLOW_BLOCK_UNBIND:
+ block_cb = flow_block_cb_lookup(f->block, cb, dev);
+ if (!block_cb)
+ return -ENOENT;
+
+- if (flow_block_cb_decref(block_cb)) {
++ if (!flow_block_cb_decref(block_cb)) {
+ flow_block_cb_remove(block_cb, f);
+ list_del(&block_cb->driver_list);
+ }