netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: davem@davemloft.net, netdev@vger.kernel.org
Subject: [PATCH 05/12] netfilter: ipset: Fix race between dump and swap
Date: Mon,  9 Oct 2017 18:25:39 +0200	[thread overview]
Message-ID: <1507566346-32553-6-git-send-email-pablo@netfilter.org> (raw)
In-Reply-To: <1507566346-32553-1-git-send-email-pablo@netfilter.org>

From: Ross Lagerwall <ross.lagerwall@citrix.com>

Fix a race between ip_set_dump_start() and ip_set_swap().
The race is as follows:
* Without holding the ref lock, ip_set_swap() checks ref_netlink of the
  set and it is 0.
* ip_set_dump_start() takes a reference on the set.
* ip_set_swap() does the swap (even though it now has a non-zero
  reference count).
* ip_set_dump_start() gets the set from ip_set_list again which is now a
  different set since it has been swapped.
* ip_set_dump_start() calls __ip_set_put_netlink() and hits a BUG_ON due
  to the reference count being 0.

Fix this race by extending the critical region in which the ref lock is
held to include checking the ref counts.

The race can be reproduced with the following script:
  while :; do
    ipset destroy hash_ip1
    ipset destroy hash_ip2
    ipset create hash_ip1 hash:ip family inet hashsize 1024 \
        maxelem 500000
    ipset create hash_ip2 hash:ip family inet hashsize 300000 \
        maxelem 500000
    ipset create hash_ip3 hash:ip family inet hashsize 1024 \
        maxelem 500000
    ipset save &
    ipset swap hash_ip3 hash_ip2
    ipset destroy hash_ip3
    wait
  done

Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Acked-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/ipset/ip_set_core.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index a7f049ff3049..cf84f7b37cd9 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -1191,14 +1191,17 @@ static int ip_set_swap(struct net *net, struct sock *ctnl, struct sk_buff *skb,
 	      from->family == to->family))
 		return -IPSET_ERR_TYPE_MISMATCH;
 
-	if (from->ref_netlink || to->ref_netlink)
+	write_lock_bh(&ip_set_ref_lock);
+
+	if (from->ref_netlink || to->ref_netlink) {
+		write_unlock_bh(&ip_set_ref_lock);
 		return -EBUSY;
+	}
 
 	strncpy(from_name, from->name, IPSET_MAXNAMELEN);
 	strncpy(from->name, to->name, IPSET_MAXNAMELEN);
 	strncpy(to->name, from_name, IPSET_MAXNAMELEN);
 
-	write_lock_bh(&ip_set_ref_lock);
 	swap(from->ref, to->ref);
 	ip_set(inst, from_id) = to;
 	ip_set(inst, to_id) = from;
-- 
2.1.4

  parent reply	other threads:[~2017-10-09 16:25 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-09 16:25 [PATCH 00/12] Netfilter/IPVS fixes for net Pablo Neira Ayuso
2017-10-09 16:25 ` [PATCH 01/12] netfilter: ipvs: full-functionality option for ECN encapsulation in tunnel Pablo Neira Ayuso
2017-10-09 16:25 ` [PATCH 02/12] netfilter: xt_socket: Restore mark from full sockets only Pablo Neira Ayuso
2017-10-09 16:25 ` [PATCH 03/12] netfilter: ipset: Fix adding an IPv4 range containing more than 2^31 addresses Pablo Neira Ayuso
2017-10-09 16:25 ` [PATCH 04/12] netfilter: ipset: pernet ops must be unregistered last Pablo Neira Ayuso
2017-10-09 16:25 ` Pablo Neira Ayuso [this message]
2017-10-09 16:25 ` [PATCH 06/12] netfilter: nf_tables: fix update chain error Pablo Neira Ayuso
2017-10-09 16:25 ` [PATCH 07/12] netfilter: ebtables: fix race condition in frame_filter_net_init() Pablo Neira Ayuso
2017-10-09 16:25 ` [PATCH 08/12] netfilter: nf_tables: Release memory obtained by kasprintf Pablo Neira Ayuso
2017-10-09 16:25 ` [PATCH 09/12] netfilter: nf_tables: do not dump chain counters if not enabled Pablo Neira Ayuso
2017-10-09 16:25 ` [PATCH 10/12] netfilter: x_tables: avoid stack-out-of-bounds read in xt_copy_counters_from_user Pablo Neira Ayuso
2017-10-09 16:25 ` [PATCH 11/12] netfilter: SYNPROXY: skip non-tcp packet in {ipv4, ipv6}_synproxy_hook Pablo Neira Ayuso
2017-10-09 16:25 ` [PATCH 12/12] netfilter: xt_bpf: Fix XT_BPF_MODE_FD_PINNED mode of 'xt_bpf_info_v1' Pablo Neira Ayuso
2017-10-09 17:40 ` [PATCH 00/12] Netfilter/IPVS fixes for net David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1507566346-32553-6-git-send-email-pablo@netfilter.org \
    --to=pablo@netfilter.org \
    --cc=davem@davemloft.net \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).