diff options
author | WANG Cong <xiyou.wangcong@gmail.com> | 2015-05-05 18:22:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-05-09 16:14:04 -0400 |
commit | d744318574090c3b796915d9d710bdb17db191a1 (patch) | |
tree | 86814b3ab96984332dc666650a574e835008516c /net/sched/cls_api.c | |
parent | 1006da19ea6603135773a79f09e4e931be460429 (diff) |
net_sched: fix a use-after-free in tc_ctl_tfilter()
When tcf_destroy() returns true, tp could be already destroyed,
we should not use tp->next after that.
For long term, we probably should move tp list to list_head.
Fixes: 1e052be69d04 ("net_sched: destroy proto tp when all filters are gone")
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/cls_api.c')
-rw-r--r-- | net/sched/cls_api.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 8b0470e418dc..b6ef9a04de06 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -308,12 +308,11 @@ replay: | |||
308 | case RTM_DELTFILTER: | 308 | case RTM_DELTFILTER: |
309 | err = tp->ops->delete(tp, fh); | 309 | err = tp->ops->delete(tp, fh); |
310 | if (err == 0) { | 310 | if (err == 0) { |
311 | tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER); | 311 | struct tcf_proto *next = rtnl_dereference(tp->next); |
312 | if (tcf_destroy(tp, false)) { | ||
313 | struct tcf_proto *next = rtnl_dereference(tp->next); | ||
314 | 312 | ||
313 | tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER); | ||
314 | if (tcf_destroy(tp, false)) | ||
315 | RCU_INIT_POINTER(*back, next); | 315 | RCU_INIT_POINTER(*back, next); |
316 | } | ||
317 | } | 316 | } |
318 | goto errout; | 317 | goto errout; |
319 | case RTM_GETTFILTER: | 318 | case RTM_GETTFILTER: |