Patch "net/sched: fix initialization order when updating chain 0 head" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net/sched: fix initialization order when updating chain 0 head

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-sched-fix-initialization-order-when-updating-cha.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 6aac5024453e201cd4e1445e79a451f22f768d40
Author: Marcelo Ricardo Leitner <marcelo.leitner@xxxxxxxxx>
Date:   Thu Apr 7 11:29:23 2022 -0300

    net/sched: fix initialization order when updating chain 0 head
    
    [ Upstream commit e65812fd22eba32f11abe28cb377cbd64cfb1ba0 ]
    
    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: 2190d1d0944f ("net: sched: introduce helpers to work with filter chains")
    Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@xxxxxxxxx>
    Signed-off-by: Vlad Buslov <vladbu@xxxxxxxxxx>
    Reviewed-by: Davide Caratti <dcaratti@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/b97d5f4eaffeeb9d058155bcab63347527261abf.1649341369.git.marcelo.leitner@xxxxxxxxx
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 80205b138d11..919c7fa5f02d 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -1639,10 +1639,10 @@ static int tcf_chain_tp_insert(struct tcf_chain *chain,
 	if (chain->flushing)
 		return -EAGAIN;
 
+	RCU_INIT_POINTER(tp->next, tcf_chain_tp_prev(chain, chain_info));
 	if (*chain_info->pprev == chain->filter_chain)
 		tcf_chain0_head_change(chain, tp);
 	tcf_proto_get(tp);
-	RCU_INIT_POINTER(tp->next, tcf_chain_tp_prev(chain, chain_info));
 	rcu_assign_pointer(*chain_info->pprev, tp);
 
 	return 0;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux