summaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorCong Wang <xiyou.wangcong@gmail.com>2020-03-28 12:12:59 -0700
committerDavid S. Miller <davem@davemloft.net>2020-04-01 11:06:23 -0700
commit304e024216a802a7dc8ba75d36de82fa136bbf3e (patch)
tree15167fc30e3b2bbc99d155f837724376c4c0a224 /net/ipv6
parent1a323ea5356edbb3073dc59d51b9e6b86908857d (diff)
downloadlinux-304e024216a802a7dc8ba75d36de82fa136bbf3e.tar.gz
linux-304e024216a802a7dc8ba75d36de82fa136bbf3e.tar.bz2
linux-304e024216a802a7dc8ba75d36de82fa136bbf3e.zip
net_sched: add a temporary refcnt for struct tcindex_data
Although we intentionally use an ordered workqueue for all tc filter works, the ordering is not guaranteed by RCU work, given that tcf_queue_work() is esstenially a call_rcu(). This problem is demostrated by Thomas: CPU 0: tcf_queue_work() tcf_queue_work(&r->rwork, tcindex_destroy_rexts_work); -> Migration to CPU 1 CPU 1: tcf_queue_work(&p->rwork, tcindex_destroy_work); so the 2nd work could be queued before the 1st one, which leads to a free-after-free. Enforcing this order in RCU work is hard as it requires to change RCU code too. Fortunately we can workaround this problem in tcindex filter by taking a temporary refcnt, we only refcnt it right before we begin to destroy it. This simplifies the code a lot as a full refcnt requires much more changes in tcindex_set_parms(). Reported-by: syzbot+46f513c3033d592409d2@syzkaller.appspotmail.com Fixes: 3d210534cc93 ("net_sched: fix a race condition in tcindex_destroy()") Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Paul E. McKenney <paulmck@kernel.org> Cc: Jamal Hadi Salim <jhs@mojatatu.com> Cc: Jiri Pirko <jiri@resnulli.us> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Reviewed-by: Paul E. McKenney <paulmck@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
0 files changed, 0 insertions, 0 deletions