Re: [PATCH] net: sched: fix crash when deleting secondary chains
From: Jiri Pirko <jiri@resnulli.us>
Date: 2017-11-19 16:23:12
Sun, Nov 19, 2017 at 12:44:05PM CET, code@rkapl.cz wrote:
If you flush (delete) a filter chain other than chain 0 (such as when
deleting the device), the kernel may run into a use-after-free. The
chain refcount must not be decremented unless we are sure we are done
with the chain.
To reproduce the bug, run:
ip link add dtest type dummy
tc qdisc add dev dtest ingress
tc filter add dev dtest chain 1 parent ffff: flower
ip link del dtest
Introduced in: commit f93e1cdcf42c ("net/sched: fix filter flushing"),
but unless you have KAsan or luck, you won't notice it until
commit 0dadc117ac8b ("cls_flower: use tcf_exts_get_net() before call_rcu()")Patch looks fine. Please repost with proper "Fixes: " tag. Feel free to add my: Acked-by: Jiri Pirko <redacted> tag. Thanks!
quoted hunk
Signed-off-by: Roman Kapl <redacted> --- net/sched/cls_api.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index ab255b421781..7d97f612c9b9 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c@@ -205,13 +205,14 @@ static void tcf_chain_head_change(struct tcf_chain *chain,static void tcf_chain_flush(struct tcf_chain *chain) { - struct tcf_proto *tp; + struct tcf_proto *tp = rtnl_dereference(chain->filter_chain); tcf_chain_head_change(chain, NULL); - while ((tp = rtnl_dereference(chain->filter_chain)) != NULL) { + while (tp) { RCU_INIT_POINTER(chain->filter_chain, tp->next); - tcf_chain_put(chain); tcf_proto_destroy(tp); + tp = rtnl_dereference(chain->filter_chain); + tcf_chain_put(chain); } } -- 2.15.0