• Julian Anastasov's avatar
    net: call rcu_read_lock early in process_backlog · eda27b22
    Julian Anastasov authored
    commit 2c17d27c upstream.
    
    Incoming packet should be either in backlog queue or
    in RCU read-side section. Otherwise, the final sequence of
    flush_backlog() and synchronize_net() may miss packets
    that can run without device reference:
    
    CPU 1                  CPU 2
                           skb->dev: no reference
                           process_backlog:__skb_dequeue
                           process_backlog:local_irq_enable
    
    on_each_cpu for
    flush_backlog =>       IPI(hardirq): flush_backlog
                           - packet not found in backlog
    
                           CPU delayed ...
    synchronize_net
    - no ongoing RCU
    read-side sections
    
    netdev_run_todo,
    rcu_barrier: no
    ongoing callbacks
                           __netif_receive_skb_core:rcu_read_lock
                           - too late
    free dev
                           process packet for freed dev
    
    Fixes: 6e583ce5 ("net: eliminate refcounting in backlog queue")
    Cc: Eric W. Biederman <ebiederm@xmission.com>
    Cc: Stephen Hemminger <stephen@networkplumber.org>
    Signed-off-by: default avatarJulian Anastasov <ja@ssi.bg>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    [lizf: Backported to 3.4:
     - adjust context
     - no need to change "goto unlock" to "goto out"]
    Signed-off-by: default avatarZefan Li <lizefan@huawei.com>
    eda27b22
dev.c 160 KB