• Yunsheng Lin's avatar
    net: sch_generic: aviod concurrent reset and enqueue op for lockless qdisc · 749cc0b0
    Yunsheng Lin authored
    [ Upstream commit 2fb541c8 ]
    
    Currently there is concurrent reset and enqueue operation for the
    same lockless qdisc when there is no lock to synchronize the
    q->enqueue() in __dev_xmit_skb() with the qdisc reset operation in
    qdisc_deactivate() called by dev_deactivate_queue(), which may cause
    out-of-bounds access for priv->ring[] in hns3 driver if user has
    requested a smaller queue num when __dev_xmit_skb() still enqueue a
    skb with a larger queue_mapping after the corresponding qdisc is
    reset, and call hns3_nic_net_xmit() with that skb later.
    
    Reused the existing synchronize_net() in dev_deactivate_many() to
    make sure skb with larger queue_mapping enqueued to old qdisc(which
    is saved in dev_queue->qdisc_sleeping) will always be reset when
    dev_reset_queue() is called.
    
    Fixes: 6b3ba914 ("net: sched: allow qdiscs to handle locking")
    Signed-off-by: default avatarYunsheng Lin <linyunsheng@huawei.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    749cc0b0
sch_generic.c 32.8 KB