[PATCH] netfilter: tproxy: Add RCU protection in nf_tproxy_laddr4
From: Jiawei Ye
Date: Wed Sep 04 2024 - 08:21:18 EST
In the `nf_tproxy_laddr4` function, both the `__in_dev_get_rcu()` call
and the `in_dev_for_each_ifa_rcu()` macro are used to access
RCU-protected data structures. Previously, these accesses were not
enclosed within an RCU read-side critical section, which violates RCU
usage rules and can lead to race conditions, data inconsistencies, and
memory corruption issues.
This possible bug was identified using a static analysis tool developed
by myself, specifically designed to detect RCU-related issues.
To address this, `rcu_read_lock()` and `rcu_read_unlock()` are added
around the RCU-protected operations in the `nf_tproxy_laddr4` function by
acquiring the RCU read lock before calling `__in_dev_get_rcu()` and
iterating with `in_dev_for_each_ifa_rcu()`. This change prevents
potential RCU issues and adheres to proper RCU usage patterns.
Fixes: b8d19572367b ("netfilter: use in_dev_for_each_ifa_rcu")
Signed-off-by: Jiawei Ye <jiawei.ye@xxxxxxxxxxx>
---
net/ipv4/netfilter/nf_tproxy_ipv4.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/ipv4/netfilter/nf_tproxy_ipv4.c b/net/ipv4/netfilter/nf_tproxy_ipv4.c
index 73e66a088e25..51ff9c337e71 100644
--- a/net/ipv4/netfilter/nf_tproxy_ipv4.c
+++ b/net/ipv4/netfilter/nf_tproxy_ipv4.c
@@ -57,8 +57,10 @@ __be32 nf_tproxy_laddr4(struct sk_buff *skb, __be32 user_laddr, __be32 daddr)
return user_laddr;
laddr = 0;
+ rcu_read_lock();
indev = __in_dev_get_rcu(skb->dev);
if (!indev)
+ rcu_read_unlock();
return daddr;
in_dev_for_each_ifa_rcu(ifa, indev) {
@@ -68,6 +70,7 @@ __be32 nf_tproxy_laddr4(struct sk_buff *skb, __be32 user_laddr, __be32 daddr)
laddr = ifa->ifa_local;
break;
}
+ rcu_read_unlock();
return laddr ? laddr : daddr;
}
--
2.34.1