• Marcelo Ricardo Leitner's avatar
    net/sched: fix initialization order when updating chain 0 head · e65812fd
    Marcelo Ricardo Leitner authored
    Currently, when inserting a new filter that needs to sit at the head
    of chain 0, it will first update the heads pointer on all devices using
    the (shared) block, and only then complete the initialization of the new
    element so that it has a "next" element.
    
    This can lead to a situation that the chain 0 head is propagated to
    another CPU before the "next" initialization is done. When this race
    condition is triggered, packets being matched on that CPU will simply
    miss all other filters, and will flow through the stack as if there were
    no other filters installed. If the system is using OVS + TC, such
    packets will get handled by vswitchd via upcall, which results in much
    higher latency and reordering. For other applications it may result in
    packet drops.
    
    This is reproducible with a tc only setup, but it varies from system to
    system. It could be reproduced with a shared block amongst 10 veth
    tunnels, and an ingress filter mirroring packets to another veth.
    That's because using the last added veth tunnel to the shared block to
    do the actual traffic, it makes the race window bigger and easier to
    trigger.
    
    The fix is rather simple, to just initialize the next pointer of the new
    filter instance (tp) before propagating the head change.
    
    The fixes tag is pointing to the original code though this issue should
    only be observed when using it unlocked.
    
    Fixes: 2190d1d0 ("net: sched: introduce helpers to work with filter chains")
    Signed-off-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
    Signed-off-by: default avatarVlad Buslov <vladbu@nvidia.com>
    Reviewed-by: default avatarDavide Caratti <dcaratti@redhat.com>
    Link: https://lore.kernel.org/r/b97d5f4eaffeeb9d058155bcab63347527261abf.1649341369.git.marcelo.leitner@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    e65812fd
cls_api.c 91.3 KB