• Cong Wang's avatar
    net_sched: add a temporary refcnt for struct tcindex_data · 304e0242
    Cong Wang authored
    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: 3d210534 ("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: default avatarCong Wang <xiyou.wangcong@gmail.com>
    Reviewed-by: default avatarPaul E. McKenney <paulmck@kernel.org>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    304e0242
cls_tcindex.c 17.3 KB