* [PATCH 0/1] ipset patch to fix race condition between swap/destroy and add/del/test, v3
@ 2023-11-13 20:09 Jozsef Kadlecsik
2023-11-13 20:09 ` [PATCH 1/1] netfilter: ipset: fix race condition between swap/destroy and kernel side add/del/test, v2 Jozsef Kadlecsik
0 siblings, 1 reply; 3+ messages in thread
From: Jozsef Kadlecsik @ 2023-11-13 20:09 UTC (permalink / raw)
To: netfilter-devel; +Cc: Pablo Neira Ayuso, Linkui Xiao, Florian Westphal
Hi Pablo,
Please apply the next patch to your nf tree, which fixes a race condition:
* There's a race between a fast swap/destroy and a slow kernel side add/del/test element
operation in ipset. The attached patch fixes it by forcing ip_set_swap() to wait for
all readers to finish accessing the old set pointers.
v2: synchronize_rcu() is moved into ip_set_swap() in order not to burden
ip_set_destroy() unnecessarily when all sets are destroyed.
v3: Florian Westphal pointed out that all netfilter hooks run with rcu_read_lock() held
and em_ipset.c wraps the entire ip_set_test() in rcu read lock/unlock pair
So there's no need to extend the rcu read locked area in ipset itse
Thanks!
Jozsef
The following changes since commit 7153a404fb70d21097af3169354e1e5fda3fbb02:
Merge tag 'nf-23-09-06' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf (2023-09-07 11:47:15 +0200)
are available in the Git repository at:
git://blackhole.kfki.hu/nf eca49fc2a1c2d
for you to fetch changes up to eca49fc2a1c2deafb870d88bef20690ecd5aeefd:
netfilter: ipset: fix race condition between swap/destroy and kernel side add/del/test, v2 (2023-11-13 21:04:43 +0100)
----------------------------------------------------------------
Jozsef Kadlecsik (1):
netfilter: ipset: fix race condition between swap/destroy and kernel side add/del/test, v2
net/netfilter/ipset/ip_set_core.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH 1/1] netfilter: ipset: fix race condition between swap/destroy and kernel side add/del/test, v2
2023-11-13 20:09 [PATCH 0/1] ipset patch to fix race condition between swap/destroy and add/del/test, v3 Jozsef Kadlecsik
@ 2023-11-13 20:09 ` Jozsef Kadlecsik
0 siblings, 0 replies; 3+ messages in thread
From: Jozsef Kadlecsik @ 2023-11-13 20:09 UTC (permalink / raw)
To: netfilter-devel; +Cc: Pablo Neira Ayuso, Linkui Xiao, Florian Westphal
Linkui Xiao reported that there's a race condition when ipset swap and destroy is
called, which can lead to crash in add/del/test element operations. Swap then
destroy are usual operations to replace a set with another one in a production
system. The issue can in some cases be reproduced with the script:
ipset create hash_ip1 hash:net family inet hashsize 1024 maxelem 1048576
ipset add hash_ip1 172.20.0.0/16
ipset add hash_ip1 192.168.0.0/16
iptables -A INPUT -m set --match-set hash_ip1 src -j ACCEPT
while [ 1 ]
do
# ... Ongoing traffic...
ipset create hash_ip2 hash:net family inet hashsize 1024 maxelem 1048576
ipset add hash_ip2 172.20.0.0/16
ipset swap hash_ip1 hash_ip2
ipset destroy hash_ip2
sleep 0.05
done
In the race case the possible order of the operations are
CPU0 CPU1
ip_set_test
ipset swap hash_ip1 hash_ip2
ipset destroy hash_ip2
hash_net_kadt
Swap replaces hash_ip1 with hash_ip2 and then destroy removes hash_ip2 which
is the original hash_ip1. ip_set_test was called on hash_ip1 and because destroy
removed it, hash_net_kadt crashes.
The fix is to force ip_set_swap() to wait for all readers to finish accessing the
old set pointers by calling synchronize_rcu().
The first version of the patch was written by Linkui Xiao <xiaolinkui@kylinos.cn>.
v2: synchronize_rcu() is moved into ip_set_swap() in order not to burden
ip_set_destroy() unnecessarily when all sets are destroyed.
v3: Florian Westphal pointed out that all netfilter hooks run with rcu_read_lock() held
and em_ipset.c wraps the entire ip_set_test() in rcu read lock/unlock pair.
So there's no need to extend the rcu read locked area in ipset itself.
Closes: https://lore.kernel.org/all/69e7963b-e7f8-3ad0-210-7b86eebf7f78@netfilter.org/
Reported by: Linkui Xiao <xiaolinkui@kylinos.cn>
Signed-off-by: Jozsef Kadlecsik <kadlec@netfilter.org>
---
net/netfilter/ipset/ip_set_core.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index e564b5174261..43cd64d6dc26 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -61,6 +61,8 @@ MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_IPSET);
ip_set_dereference((inst)->ip_set_list)[id]
#define ip_set_ref_netlink(inst,id) \
rcu_dereference_raw((inst)->ip_set_list)[id]
+#define ip_set_dereference_nfnl(p) \
+ rcu_dereference_check(p, lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET))
/* The set types are implemented in modules and registered set types
* can be found in ip_set_type_list. Adding/deleting types is
@@ -700,15 +702,10 @@ __ip_set_put_netlink(struct ip_set *set)
static struct ip_set *
ip_set_rcu_get(struct net *net, ip_set_id_t index)
{
- struct ip_set *set;
struct ip_set_net *inst = ip_set_pernet(net);
- rcu_read_lock();
- /* ip_set_list itself needs to be protected */
- set = rcu_dereference(inst->ip_set_list)[index];
- rcu_read_unlock();
-
- return set;
+ /* ip_set_list and the set pointer need to be protected */
+ return ip_set_dereference_nfnl(inst->ip_set_list)[index];
}
static inline void
@@ -1389,6 +1386,9 @@ static int ip_set_swap(struct sk_buff *skb, const struct nfnl_info *info,
ip_set(inst, to_id) = from;
write_unlock_bh(&ip_set_ref_lock);
+ /* Make sure all readers of the old set pointers are completed. */
+ synchronize_rcu();
+
return 0;
}
--
2.30.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 0/1] ipset patch to fix race condition between swap/destroy and add/del/test, v3
@ 2023-11-13 20:13 Jozsef Kadlecsik
0 siblings, 0 replies; 3+ messages in thread
From: Jozsef Kadlecsik @ 2023-11-13 20:13 UTC (permalink / raw)
To: netfilter-devel; +Cc: Pablo Neira Ayuso, Linkui Xiao, Florian Westphal
Hi Pablo,
[Resend: sorry, patch subject was not updated properly.]
Please apply the next patch to your nf tree, which fixes a race condition:
* There's a race between a fast swap/destroy and a slow kernel side add/del/test element
operation in ipset. The attached patch fixes it by forcing ip_set_swap() to wait for
all readers to finish accessing the old set pointers.
v2: synchronize_rcu() is moved into ip_set_swap() in order not to burden
ip_set_destroy() unnecessarily when all sets are destroyed.
v3: Florian Westphal pointed out that all netfilter hooks run with rcu_read_lock() held
and em_ipset.c wraps the entire ip_set_test() in rcu read lock/unlock pair
So there's no need to extend the rcu read locked area in ipset itse
Thanks!
Jozsef
The following changes since commit 7153a404fb70d21097af3169354e1e5fda3fbb02:
Merge tag 'nf-23-09-06' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf (2023-09-07 11:47:15 +0200)
are available in the Git repository at:
git://blackhole.kfki.hu/nf 2c9d59f0074ade
for you to fetch changes up to 2c9d59f0074ade26f2324209383d3699ad1790be:
netfilter: ipset: fix race condition between swap/destroy and kernel side add/del/test, v3 (2023-11-13 21:10:42 +0100)
----------------------------------------------------------------
Jozsef Kadlecsik (1):
netfilter: ipset: fix race condition between swap/destroy and kernel side add/del/test, v3
net/netfilter/ipset/ip_set_core.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2023-11-13 20:13 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-13 20:09 [PATCH 0/1] ipset patch to fix race condition between swap/destroy and add/del/test, v3 Jozsef Kadlecsik
2023-11-13 20:09 ` [PATCH 1/1] netfilter: ipset: fix race condition between swap/destroy and kernel side add/del/test, v2 Jozsef Kadlecsik
-- strict thread matches above, loose matches on Subject: below --
2023-11-13 20:13 [PATCH 0/1] ipset patch to fix race condition between swap/destroy and add/del/test, v3 Jozsef Kadlecsik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).