summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2022-11-29 19:48:09 +0300
committerJakub Kicinski <kuba@kernel.org>2022-12-02 07:26:21 +0300
commit5aa2820177af650293b2f9f1873c1f6f8e4ad7a4 (patch)
tree41d0ba065d1e740895121a095a1811a42bb565c1 /net
parente012764cebf6e33097f6833ff15a936fbe7b846c (diff)
downloadlinux-5aa2820177af650293b2f9f1873c1f6f8e4ad7a4.tar.xz
hsr: Add a rcu-read lock to hsr_forward_skb().
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>
Diffstat (limited to 'net')
-rw-r--r--net/hsr/hsr_forward.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
index 3e58d310b4d4..a8befa35841e 100644
--- a/net/hsr/hsr_forward.c
+++ b/net/hsr/hsr_forward.c
@@ -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);
}