Patch "netfilter: ipset: Fix race between IPSET_CMD_CREATE and IPSET_CMD_SWAP" has been added to the 6.5-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

    netfilter: ipset: Fix race between IPSET_CMD_CREATE and IPSET_CMD_SWAP

to the 6.5-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:
     netfilter-ipset-fix-race-between-ipset_cmd_create-an.patch
and it can be found in the queue-6.5 subdirectory.

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



commit 4a20f419bf183103ff39cc7706333996e1f022fb
Author: Jozsef Kadlecsik <kadlec@xxxxxxxxxxxxx>
Date:   Tue Sep 19 20:04:45 2023 +0200

    netfilter: ipset: Fix race between IPSET_CMD_CREATE and IPSET_CMD_SWAP
    
    [ Upstream commit 7433b6d2afd512d04398c73aa984d1e285be125b ]
    
    Kyle Zeng reported that there is a race between IPSET_CMD_ADD and IPSET_CMD_SWAP
    in netfilter/ip_set, which can lead to the invocation of `__ip_set_put` on a
    wrong `set`, triggering the `BUG_ON(set->ref == 0);` check in it.
    
    The race is caused by using the wrong reference counter, i.e. the ref counter instead
    of ref_netlink.
    
    Fixes: 24e227896bbf ("netfilter: ipset: Add schedule point in call_ad().")
    Reported-by: Kyle Zeng <zengyhkyle@xxxxxxxxx>
    Closes: https://lore.kernel.org/netfilter-devel/ZPZqetxOmH+w%2Fmyc@westworld/#r
    Tested-by: Kyle Zeng <zengyhkyle@xxxxxxxxx>
    Signed-off-by: Jozsef Kadlecsik <kadlec@xxxxxxxxxxxxx>
    Signed-off-by: Florian Westphal <fw@xxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 0b68e2e2824e1..58608460cf6df 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -682,6 +682,14 @@ __ip_set_put(struct ip_set *set)
 /* set->ref can be swapped out by ip_set_swap, netlink events (like dump) need
  * a separate reference counter
  */
+static void
+__ip_set_get_netlink(struct ip_set *set)
+{
+	write_lock_bh(&ip_set_ref_lock);
+	set->ref_netlink++;
+	write_unlock_bh(&ip_set_ref_lock);
+}
+
 static void
 __ip_set_put_netlink(struct ip_set *set)
 {
@@ -1693,11 +1701,11 @@ call_ad(struct net *net, struct sock *ctnl, struct sk_buff *skb,
 
 	do {
 		if (retried) {
-			__ip_set_get(set);
+			__ip_set_get_netlink(set);
 			nfnl_unlock(NFNL_SUBSYS_IPSET);
 			cond_resched();
 			nfnl_lock(NFNL_SUBSYS_IPSET);
-			__ip_set_put(set);
+			__ip_set_put_netlink(set);
 		}
 
 		ip_set_lock(set);



[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