All of lore.kernel.org
 help / color / mirror / Atom feed
* [Patch net] net_sched: cls_route: free the old filter only when it has been removed
@ 2022-06-18  6:18 chenzhen 00642392
  2022-06-20 18:28 ` Cong Wang
  0 siblings, 1 reply; 2+ messages in thread
From: chenzhen 00642392 @ 2022-06-18  6:18 UTC (permalink / raw)
  To: netdev; +Cc: jhs, xiyou.wangcong, jiri, rose.chen

From: Zhen Chen <chenzhen126@huawei.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@syzkaller.appspotmail.com
Fixes: 1109c00547fc ("net: sched: RCU cls_route")
Signed-off-by: Zhen Chen <chenzhen126@huawei.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


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [Patch net] net_sched: cls_route: free the old filter only when it has been removed
  2022-06-18  6:18 [Patch net] net_sched: cls_route: free the old filter only when it has been removed chenzhen 00642392
@ 2022-06-20 18:28 ` Cong Wang
  0 siblings, 0 replies; 2+ messages in thread
From: Cong Wang @ 2022-06-20 18:28 UTC (permalink / raw)
  To: chenzhen 00642392
  Cc: Linux Kernel Network Developers, Jamal Hadi Salim, Jiri Pirko,
	Chenxiang (EulerOS)

On Fri, Jun 17, 2022 at 11:20 PM chenzhen 00642392
<chenzhen126@huawei.com> wrote:
>
> From: Zhen Chen <chenzhen126@huawei.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.

This seems reasonable but see below.

>
> Fix this by putting the free logic together with the remove action.

This does not look correct. You just move the deletion logic upper to
a narrowed case. The if case you moved to also does the deletion
without your patch, so I fail to see how this could solve the problem.

If we just follow your logic here, should we have the following patch
instead? But I am still not sure whether we need to treat the 0 handle
special here.

diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index a35ab8c27866..758c21f9d628 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -526,7 +526,7 @@ static int route4_change(struct net *net, struct
sk_buff *in_skb,
        rcu_assign_pointer(f->next, f1);
        rcu_assign_pointer(*fp, f);

-       if (fold && fold->handle && f->handle != fold->handle) {
+       if (fold && f->handle != fold->handle) {
                th = to_hash(fold->handle);
                h = from_hash(fold->handle >> 16);
                b = rtnl_dereference(head->table[th]);

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-06-20 18:29 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-18  6:18 [Patch net] net_sched: cls_route: free the old filter only when it has been removed chenzhen 00642392
2022-06-20 18:28 ` Cong Wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.