• P
    [NET_SCHED]: Fix fallout from dev->qdisc RCU change · 85670cc1
    Patrick McHardy 提交于
    The move of qdisc destruction to a rcu callback broke locking in the
    entire qdisc layer by invalidating previously valid assumptions about
    the context in which changes to the qdisc tree occur.
    
    The two assumptions were:
    
    - since changes only happen in process context, read_lock doesn't need
      bottem half protection. Now invalid since destruction of inner qdiscs,
      classifiers, actions and estimators happens in the RCU callback unless
      they're manually deleted, resulting in dead-locks when read_lock in
      process context is interrupted by write_lock_bh in bottem half context.
    
    - since changes only happen under the RTNL, no additional locking is
      necessary for data not used during packet processing (f.e. u32_list).
      Again, since destruction now happens in the RCU callback, this assumption
      is not valid anymore, causing races while using this data, which can
      result in corruption or use-after-free.
    
    Instead of "fixing" this by disabling bottem halfs everywhere and adding
    new locks/refcounting, this patch makes these assumptions valid again by
    moving destruction back to process context. Since only the dev->qdisc
    pointer is protected by RCU, but ->enqueue and the qdisc tree are still
    protected by dev->qdisc_lock, destruction of the tree can be performed
    immediately and only the final free needs to happen in the rcu callback
    to make sure dev_queue_xmit doesn't access already freed memory.
    Signed-off-by: NPatrick McHardy <kaber@trash.net>
    Signed-off-by: NDavid S. Miller <davem@davemloft.net>
    85670cc1
cls_api.c 14.6 KB