[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20220618061840.1012529-1-chenzhen126@huawei.com>
Date: Sat, 18 Jun 2022 14:18:40 +0800
From: chenzhen 00642392 <chenzhen126@...wei.com>
To: <netdev@...r.kernel.org>
CC: <jhs@...atatu.com>, <xiyou.wangcong@...il.com>, <jiri@...nulli.us>,
<rose.chen@...wei.com>
Subject: [Patch net] net_sched: cls_route: free the old filter only when it has been removed
From: Zhen Chen <chenzhen126@...wei.com>
Syzbot reported a ODEBUG bug in route4_destroy(), it is actually a
use-after-free issue when route4_destroy() goes through the hashtable.
The root cause is that after route4_change() inserts a new filter into the
hashtable and finds an old filter, it will not remove the old one from the
table if fold->handle is 0, but free the fold as the final step.
Fix this by putting the free logic together with the remove action.
Reported-and-tested-by: syzbot+2e3efb5eb71cb5075ba7@...kaller.appspotmail.com
Fixes: 1109c00547fc ("net: sched: RCU cls_route")
Signed-off-by: Zhen Chen <chenzhen126@...wei.com>
---
net/sched/cls_route.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index a35ab8c27866..3917b84700b4 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -536,6 +536,9 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
fp = &pfp->next, pfp = rtnl_dereference(*fp)) {
if (pfp == fold) {
rcu_assign_pointer(*fp, fold->next);
+ tcf_unbind_filter(tp, &fold->res);
+ tcf_exts_get_net(&fold->exts);
+ tcf_queue_work(&fold->rwork, route4_delete_filter_work);
break;
}
}
@@ -544,11 +547,6 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
route4_reset_fastmap(head);
*arg = f;
- if (fold) {
- tcf_unbind_filter(tp, &fold->res);
- tcf_exts_get_net(&fold->exts);
- tcf_queue_work(&fold->rwork, route4_delete_filter_work);
- }
return 0;
errout:
--
2.23.0
Powered by blists - more mailing lists