hsr: Add a rcu-read lock to hsr_forward_skb().
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Tue, 29 Nov 2022 16:48:09 +0000 (17:48 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 31 Dec 2022 12:32:21 +0000 (13:32 +0100)
[ Upstream commit 5aa2820177af650293b2f9f1873c1f6f8e4ad7a4 ]

hsr_forward_skb() a skb and keeps information in an on-stack
hsr_frame_info. hsr_get_node() assigns hsr_frame_info::node_src which is
from a RCU list. This pointer is used later in hsr_forward_do().
I don't see a reason why this pointer can't vanish midway since there is
no guarantee that hsr_forward_skb() is invoked from an RCU read section.

Use rcu_read_lock() to protect hsr_frame_info::node_src from its
assignment until it is no longer used.

Fixes: f266a683a4804 ("net/hsr: Better frame dispatch")
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/hsr/hsr_forward.c

index 3e58d31..a8befa3 100644 (file)
@@ -614,11 +614,13 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port)
 {
        struct hsr_frame_info frame;
 
+       rcu_read_lock();
        if (fill_frame_info(&frame, skb, port) < 0)
                goto out_drop;
 
        hsr_register_frame_in(frame.node_src, port, frame.sequence_nr);
        hsr_forward_do(&frame);
+       rcu_read_unlock();
        /* Gets called for ingress frames as well as egress from master port.
         * So check and increment stats for master port only here.
         */
@@ -633,6 +635,7 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port)
        return;
 
 out_drop:
+       rcu_read_unlock();
        port->dev->stats.tx_dropped++;
        kfree_skb(skb);
 }