54e48df4446c639a9a6f918dfc3c5d8888c95483
[openwrt/openwrt.git] /
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Thu, 17 Nov 2022 11:58:21 +0100
3 Subject: [PATCH] net: ethernet: mtk_eth_soc: fix flow_offload related refcount
4 bug
5
6 Since we call flow_block_cb_decref on FLOW_BLOCK_UNBIND, we need to call
7 flow_block_cb_incref unconditionally, even for a newly allocated cb.
8 Fixes a use-after-free bug
9
10 Fixes: 502e84e2382d ("net: ethernet: mtk_eth_soc: add flow offloading support")
11 Signed-off-by: Felix Fietkau <nbd@nbd.name>
12 ---
13
14 --- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
15 +++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
16 @@ -554,6 +554,7 @@ mtk_eth_setup_tc_block(struct net_device
17 struct mtk_eth *eth = mac->hw;
18 static LIST_HEAD(block_cb_list);
19 struct flow_block_cb *block_cb;
20 + bool register_block = false;
21 flow_setup_cb_t *cb;
22
23 if (!eth->soc->offload_version)
24 @@ -568,16 +569,20 @@ mtk_eth_setup_tc_block(struct net_device
25 switch (f->command) {
26 case FLOW_BLOCK_BIND:
27 block_cb = flow_block_cb_lookup(f->block, cb, dev);
28 - if (block_cb) {
29 - flow_block_cb_incref(block_cb);
30 - return 0;
31 + if (!block_cb) {
32 + block_cb = flow_block_cb_alloc(cb, dev, dev, NULL);
33 + if (IS_ERR(block_cb))
34 + return PTR_ERR(block_cb);
35 +
36 + register_block = true;
37 }
38 - block_cb = flow_block_cb_alloc(cb, dev, dev, NULL);
39 - if (IS_ERR(block_cb))
40 - return PTR_ERR(block_cb);
41
42 - flow_block_cb_add(block_cb, f);
43 - list_add_tail(&block_cb->driver_list, &block_cb_list);
44 + flow_block_cb_incref(block_cb);
45 +
46 + if (register_block) {
47 + flow_block_cb_add(block_cb, f);
48 + list_add_tail(&block_cb->driver_list, &block_cb_list);
49 + }
50 return 0;
51 case FLOW_BLOCK_UNBIND:
52 block_cb = flow_block_cb_lookup(f->block, cb, dev);