From patchwork Sat Oct 27 16:05:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jozsef Kadlecsik X-Patchwork-Id: 989916 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=blackhole.kfki.hu Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=blackhole.kfki.hu header.i=@blackhole.kfki.hu header.b="MkRpumrg"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42j5Ls0rpjz9sCc for ; Sun, 28 Oct 2018 03:05:57 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728765AbeJ1ArP (ORCPT ); Sat, 27 Oct 2018 20:47:15 -0400 Received: from smtp-out.kfki.hu ([148.6.0.45]:33273 "EHLO smtp-out.kfki.hu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728739AbeJ1ArP (ORCPT ); Sat, 27 Oct 2018 20:47:15 -0400 Received: from localhost (localhost [127.0.0.1]) by smtp0.kfki.hu (Postfix) with ESMTP id 1D011674010E; Sat, 27 Oct 2018 18:05:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= blackhole.kfki.hu; h=references:in-reply-to:x-mailer:message-id :date:date:from:from:received:received:received; s=20151130; t= 1540656344; x=1542470745; bh=EzxHAErf6E1G87+4yUJdvLaBbFi/2d3jdh/ ZDS+EUtA=; b=MkRpumrg9QYEfbUMFcQ83797vV5LPnncDQdvjYnlcL8GGjAve1Z ppb+i3OdH5tDHd6TC6AIrd3DoBznaCoEuqOnnQYOIViOZOu6WANPo75wRImBtmS8 BT8pWZj/lzavTsKIlfPVbgZOsohTE1r4k633H8c2ot9m0GdN4oavZ470= X-Virus-Scanned: Debian amavisd-new at smtp0.kfki.hu Received: from smtp0.kfki.hu ([127.0.0.1]) by localhost (smtp0.kfki.hu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP; Sat, 27 Oct 2018 18:05:44 +0200 (CEST) Received: from blackhole.kfki.hu (blackhole.kfki.hu [IPv6:2001:738:5001:1::240:2]) by smtp0.kfki.hu (Postfix) with ESMTP id EB593674010D; Sat, 27 Oct 2018 18:05:43 +0200 (CEST) Received: by blackhole.kfki.hu (Postfix, from userid 1000) id C93DE20576; Sat, 27 Oct 2018 18:05:43 +0200 (CEST) From: Jozsef Kadlecsik To: netfilter-devel@vger.kernel.org Cc: Pablo Neira Ayuso Subject: [PATCH 1/5] netfilter: ipset: list:set: Decrease refcount synchronously on deletion and replace Date: Sat, 27 Oct 2018 18:05:39 +0200 Message-Id: <1540656343-822-2-git-send-email-kadlec@blackhole.kfki.hu> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1540656343-822-1-git-send-email-kadlec@blackhole.kfki.hu> References: <1540656343-822-1-git-send-email-kadlec@blackhole.kfki.hu> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org From: Stefano Brivio Commit 45040978c899 ("netfilter: ipset: Fix set:list type crash when flush/dump set in parallel") postponed decreasing set reference counters to the RCU callback. An 'ipset del' command can terminate before the RCU grace period is elapsed, and if sets are listed before then, the reference counter shown in userspace will be wrong: # ipset create h hash:ip; ipset create l list:set; ipset add l # ipset del l h; ipset list h Name: h Type: hash:ip Revision: 4 Header: family inet hashsize 1024 maxelem 65536 Size in memory: 88 References: 1 Number of entries: 0 Members: # sleep 1; ipset list h Name: h Type: hash:ip Revision: 4 Header: family inet hashsize 1024 maxelem 65536 Size in memory: 88 References: 0 Number of entries: 0 Members: Fix this by making the reference count update synchronous again. As a result, when sets are listed, ip_set_name_byindex() might now fetch a set whose reference count is already zero. Instead of relying on the reference count to protect against concurrent set renaming, grab ip_set_ref_lock as reader and copy the name, while holding the same lock in ip_set_rename() as writer instead. Reported-by: Li Shuang Fixes: 45040978c899 ("netfilter: ipset: Fix set:list type crash when flush/dump set in parallel") Signed-off-by: Stefano Brivio Signed-off-by: Jozsef Kadlecsik --- include/linux/netfilter/ipset/ip_set.h | 2 +- net/netfilter/ipset/ip_set_core.c | 23 +++++++++++------------ net/netfilter/ipset/ip_set_list_set.c | 17 +++++++++++------ 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h index 34fc80f..1d100ef 100644 --- a/include/linux/netfilter/ipset/ip_set.h +++ b/include/linux/netfilter/ipset/ip_set.h @@ -314,7 +314,7 @@ enum { extern ip_set_id_t ip_set_get_byname(struct net *net, const char *name, struct ip_set **set); extern void ip_set_put_byindex(struct net *net, ip_set_id_t index); -extern const char *ip_set_name_byindex(struct net *net, ip_set_id_t index); +extern void ip_set_name_byindex(struct net *net, ip_set_id_t index, char *name); extern ip_set_id_t ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index); extern void ip_set_nfnl_put(struct net *net, ip_set_id_t index); diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index bc4bd247..fa15a83 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c @@ -693,21 +693,20 @@ ip_set_put_byindex(struct net *net, ip_set_id_t index) EXPORT_SYMBOL_GPL(ip_set_put_byindex); /* Get the name of a set behind a set index. - * We assume the set is referenced, so it does exist and - * can't be destroyed. The set cannot be renamed due to - * the referencing either. - * + * Set itself is protected by RCU, but its name isn't: to protect against + * renaming, grab ip_set_ref_lock as reader (see ip_set_rename()) and copy the + * name. */ -const char * -ip_set_name_byindex(struct net *net, ip_set_id_t index) +void +ip_set_name_byindex(struct net *net, ip_set_id_t index, char *name) { - const struct ip_set *set = ip_set_rcu_get(net, index); + struct ip_set *set = ip_set_rcu_get(net, index); BUG_ON(!set); - BUG_ON(set->ref == 0); - /* Referenced, so it's safe */ - return set->name; + read_lock_bh(&ip_set_ref_lock); + strncpy(name, set->name, IPSET_MAXNAMELEN); + read_unlock_bh(&ip_set_ref_lock); } EXPORT_SYMBOL_GPL(ip_set_name_byindex); @@ -1153,7 +1152,7 @@ static int ip_set_rename(struct net *net, struct sock *ctnl, if (!set) return -ENOENT; - read_lock_bh(&ip_set_ref_lock); + write_lock_bh(&ip_set_ref_lock); if (set->ref != 0) { ret = -IPSET_ERR_REFERENCED; goto out; @@ -1170,7 +1169,7 @@ static int ip_set_rename(struct net *net, struct sock *ctnl, strncpy(set->name, name2, IPSET_MAXNAMELEN); out: - read_unlock_bh(&ip_set_ref_lock); + write_unlock_bh(&ip_set_ref_lock); return ret; } diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c index 072a658..4eef55d 100644 --- a/net/netfilter/ipset/ip_set_list_set.c +++ b/net/netfilter/ipset/ip_set_list_set.c @@ -148,9 +148,7 @@ __list_set_del_rcu(struct rcu_head * rcu) { struct set_elem *e = container_of(rcu, struct set_elem, rcu); struct ip_set *set = e->set; - struct list_set *map = set->data; - ip_set_put_byindex(map->net, e->id); ip_set_ext_destroy(set, e); kfree(e); } @@ -158,15 +156,21 @@ __list_set_del_rcu(struct rcu_head * rcu) static inline void list_set_del(struct ip_set *set, struct set_elem *e) { + struct list_set *map = set->data; + set->elements--; list_del_rcu(&e->list); + ip_set_put_byindex(map->net, e->id); call_rcu(&e->rcu, __list_set_del_rcu); } static inline void -list_set_replace(struct set_elem *e, struct set_elem *old) +list_set_replace(struct ip_set *set, struct set_elem *e, struct set_elem *old) { + struct list_set *map = set->data; + list_replace_rcu(&old->list, &e->list); + ip_set_put_byindex(map->net, old->id); call_rcu(&old->rcu, __list_set_del_rcu); } @@ -298,7 +302,7 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext, INIT_LIST_HEAD(&e->list); list_set_init_extensions(set, ext, e); if (n) - list_set_replace(e, n); + list_set_replace(set, e, n); else if (next) list_add_tail_rcu(&e->list, &next->list); else if (prev) @@ -486,6 +490,7 @@ list_set_list(const struct ip_set *set, const struct list_set *map = set->data; struct nlattr *atd, *nested; u32 i = 0, first = cb->args[IPSET_CB_ARG0]; + char name[IPSET_MAXNAMELEN]; struct set_elem *e; int ret = 0; @@ -504,8 +509,8 @@ list_set_list(const struct ip_set *set, nested = ipset_nest_start(skb, IPSET_ATTR_DATA); if (!nested) goto nla_put_failure; - if (nla_put_string(skb, IPSET_ATTR_NAME, - ip_set_name_byindex(map->net, e->id))) + ip_set_name_byindex(map->net, e->id, name); + if (nla_put_string(skb, IPSET_ATTR_NAME, name)) goto nla_put_failure; if (ip_set_put_extensions(skb, set, e, true)) goto nla_put_failure; From patchwork Sat Oct 27 16:05:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jozsef Kadlecsik X-Patchwork-Id: 989914 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=blackhole.kfki.hu Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=blackhole.kfki.hu header.i=@blackhole.kfki.hu header.b="oJs4S2CN"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42j5Lq5PyGz9sCc for ; Sun, 28 Oct 2018 03:05:55 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728764AbeJ1ArP (ORCPT ); Sat, 27 Oct 2018 20:47:15 -0400 Received: from smtp-out.kfki.hu ([148.6.0.48]:60987 "EHLO smtp-out.kfki.hu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728741AbeJ1ArP (ORCPT ); Sat, 27 Oct 2018 20:47:15 -0400 Received: from localhost (localhost [127.0.0.1]) by smtp2.kfki.hu (Postfix) with ESMTP id 2D1C9CC012B; Sat, 27 Oct 2018 18:05:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= blackhole.kfki.hu; h=references:in-reply-to:x-mailer:message-id :date:date:from:from:received:received:received; s=20151130; t= 1540656344; x=1542470745; bh=QFyYeLMsZ/+esXHo+W8sH9almA5PYafgWYO iRBRtUvc=; b=oJs4S2CNM4oE35WIeGd6kause9f6rJ4tj3ZczwY/3DZpqdtgjp9 wpuczRyDjb9Pzt9hgU9ZxN4OpqlunAMQGcxk3ugFldir9OENJU0PGyI8prlpW0Sm cGcscV7WRgaISl7Qs4bobATTjiEv1tXELClcoJ2G/a02OM8PozC4Xr2g= X-Virus-Scanned: Debian amavisd-new at smtp2.kfki.hu Received: from smtp2.kfki.hu ([127.0.0.1]) by localhost (smtp2.kfki.hu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP; Sat, 27 Oct 2018 18:05:44 +0200 (CEST) Received: from blackhole.kfki.hu (blackhole.kfki.hu [148.6.240.2]) by smtp2.kfki.hu (Postfix) with ESMTP id 0C34CCC012F; Sat, 27 Oct 2018 18:05:44 +0200 (CEST) Received: by blackhole.kfki.hu (Postfix, from userid 1000) id DF35F21F1B; Sat, 27 Oct 2018 18:05:43 +0200 (CEST) From: Jozsef Kadlecsik To: netfilter-devel@vger.kernel.org Cc: Pablo Neira Ayuso Subject: [PATCH 2/5] netfilter: ipset: actually allow allowable CIDR 0 in hash:net, port, net Date: Sat, 27 Oct 2018 18:05:40 +0200 Message-Id: <1540656343-822-3-git-send-email-kadlec@blackhole.kfki.hu> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1540656343-822-1-git-send-email-kadlec@blackhole.kfki.hu> References: <1540656343-822-1-git-send-email-kadlec@blackhole.kfki.hu> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org From: Eric Westbrook Allow /0 as advertised for hash:net,port,net sets. For "hash:net,port,net", ipset(8) says that "either subnet is permitted to be a /0 should you wish to match port between all destinations." Make that statement true. Before: # ipset create cidrzero hash:net,port,net # ipset add cidrzero 0.0.0.0/0,12345,0.0.0.0/0 ipset v6.34: The value of the CIDR parameter of the IP address is invalid # ipset create cidrzero6 hash:net,port,net family inet6 # ipset add cidrzero6 ::/0,12345,::/0 ipset v6.34: The value of the CIDR parameter of the IP address is invalid After: # ipset create cidrzero hash:net,port,net # ipset add cidrzero 0.0.0.0/0,12345,0.0.0.0/0 # ipset test cidrzero 192.168.205.129,12345,172.16.205.129 192.168.205.129,tcp:12345,172.16.205.129 is in set cidrzero. # ipset create cidrzero6 hash:net,port,net family inet6 # ipset add cidrzero6 ::/0,12345,::/0 # ipset test cidrzero6 fe80::1,12345,ff00::1 fe80::1,tcp:12345,ff00::1 is in set cidrzero6. See also: https://bugzilla.kernel.org/show_bug.cgi?id=200897 https://github.com/ewestbrook/linux/commit/df7ff6efb0934ab6acc11f003ff1a7580d6c1d9c Signed-off-by: Eric Westbrook Signed-off-by: Jozsef Kadlecsik --- net/netfilter/ipset/ip_set_hash_netportnet.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c index d391485..613e18e 100644 --- a/net/netfilter/ipset/ip_set_hash_netportnet.c +++ b/net/netfilter/ipset/ip_set_hash_netportnet.c @@ -213,13 +213,13 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[], if (tb[IPSET_ATTR_CIDR]) { e.cidr[0] = nla_get_u8(tb[IPSET_ATTR_CIDR]); - if (!e.cidr[0] || e.cidr[0] > HOST_MASK) + if (e.cidr[0] > HOST_MASK) return -IPSET_ERR_INVALID_CIDR; } if (tb[IPSET_ATTR_CIDR2]) { e.cidr[1] = nla_get_u8(tb[IPSET_ATTR_CIDR2]); - if (!e.cidr[1] || e.cidr[1] > HOST_MASK) + if (e.cidr[1] > HOST_MASK) return -IPSET_ERR_INVALID_CIDR; } @@ -493,13 +493,13 @@ hash_netportnet6_uadt(struct ip_set *set, struct nlattr *tb[], if (tb[IPSET_ATTR_CIDR]) { e.cidr[0] = nla_get_u8(tb[IPSET_ATTR_CIDR]); - if (!e.cidr[0] || e.cidr[0] > HOST_MASK) + if (e.cidr[0] > HOST_MASK) return -IPSET_ERR_INVALID_CIDR; } if (tb[IPSET_ATTR_CIDR2]) { e.cidr[1] = nla_get_u8(tb[IPSET_ATTR_CIDR2]); - if (!e.cidr[1] || e.cidr[1] > HOST_MASK) + if (e.cidr[1] > HOST_MASK) return -IPSET_ERR_INVALID_CIDR; } From patchwork Sat Oct 27 16:05:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jozsef Kadlecsik X-Patchwork-Id: 989915 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=blackhole.kfki.hu Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=blackhole.kfki.hu header.i=@blackhole.kfki.hu header.b="rtlKnLa7"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42j5Lr38vQz9sCm for ; Sun, 28 Oct 2018 03:05:56 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728766AbeJ1ArP (ORCPT ); Sat, 27 Oct 2018 20:47:15 -0400 Received: from smtp-out.kfki.hu ([148.6.0.46]:45847 "EHLO smtp-out.kfki.hu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728745AbeJ1ArP (ORCPT ); Sat, 27 Oct 2018 20:47:15 -0400 Received: from localhost (localhost [127.0.0.1]) by smtp1.kfki.hu (Postfix) with ESMTP id 147183C8011E; Sat, 27 Oct 2018 18:05:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= blackhole.kfki.hu; h=references:in-reply-to:x-mailer:message-id :date:date:from:from:received:received:received; s=20151130; t= 1540656344; x=1542470745; bh=EqoMOGJNIAiXZlOyJbD4tpy5nJquCm5v9H4 cFV4gcxs=; b=rtlKnLa7vBSuvwOVtmnS5atF2W4YeLIcPYLe+rQbhJ+zMWoj0B/ Vvy3o/jmIdR7nj50z7ivXv+26u8nyB1T8MX/4zkOEM66/ZRTdymI8OwSYri43QK7 s5PALM1BtTkxmNJ8twDsEs0mdeeVDmnkO5/EFAQbgRaUqs90LjMMdWwQ= X-Virus-Scanned: Debian amavisd-new at smtp1.kfki.hu Received: from smtp1.kfki.hu ([127.0.0.1]) by localhost (smtp1.kfki.hu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP; Sat, 27 Oct 2018 18:05:44 +0200 (CEST) Received: from blackhole.kfki.hu (blackhole.kfki.hu [IPv6:2001:738:5001:1::240:2]) by smtp1.kfki.hu (Postfix) with ESMTP id 174AD3C8011A; Sat, 27 Oct 2018 18:05:44 +0200 (CEST) Received: by blackhole.kfki.hu (Postfix, from userid 1000) id F0F5921FBD; Sat, 27 Oct 2018 18:05:43 +0200 (CEST) From: Jozsef Kadlecsik To: netfilter-devel@vger.kernel.org Cc: Pablo Neira Ayuso Subject: [PATCH 3/5] netfilter: ipset: fix ip_set_list allocation failure Date: Sat, 27 Oct 2018 18:05:41 +0200 Message-Id: <1540656343-822-4-git-send-email-kadlec@blackhole.kfki.hu> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1540656343-822-1-git-send-email-kadlec@blackhole.kfki.hu> References: <1540656343-822-1-git-send-email-kadlec@blackhole.kfki.hu> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org From: Andrey Ryabinin ip_set_create() and ip_set_net_init() attempt to allocate physically contiguous memory for ip_set_list. If memory is fragmented, the allocations could easily fail: vzctl: page allocation failure: order:7, mode:0xc0d0 Call Trace: dump_stack+0x19/0x1b warn_alloc_failed+0x110/0x180 __alloc_pages_nodemask+0x7bf/0xc60 alloc_pages_current+0x98/0x110 kmalloc_order+0x18/0x40 kmalloc_order_trace+0x26/0xa0 __kmalloc+0x279/0x290 ip_set_net_init+0x4b/0x90 [ip_set] ops_init+0x3b/0xb0 setup_net+0xbb/0x170 copy_net_ns+0xf1/0x1c0 create_new_namespaces+0xf9/0x180 copy_namespaces+0x8e/0xd0 copy_process+0xb61/0x1a00 do_fork+0x91/0x320 Use kvcalloc() to fallback to 0-order allocations if high order page isn't available. Signed-off-by: Andrey Ryabinin Signed-off-by: Jozsef Kadlecsik --- net/netfilter/ipset/ip_set_core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index fa15a83..68db946 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c @@ -960,7 +960,7 @@ static int ip_set_create(struct net *net, struct sock *ctnl, /* Wraparound */ goto cleanup; - list = kcalloc(i, sizeof(struct ip_set *), GFP_KERNEL); + list = kvcalloc(i, sizeof(struct ip_set *), GFP_KERNEL); if (!list) goto cleanup; /* nfnl mutex is held, both lists are valid */ @@ -972,7 +972,7 @@ static int ip_set_create(struct net *net, struct sock *ctnl, /* Use new list */ index = inst->ip_set_max; inst->ip_set_max = i; - kfree(tmp); + kvfree(tmp); ret = 0; } else if (ret) { goto cleanup; @@ -2058,7 +2058,7 @@ ip_set_net_init(struct net *net) if (inst->ip_set_max >= IPSET_INVALID_ID) inst->ip_set_max = IPSET_INVALID_ID - 1; - list = kcalloc(inst->ip_set_max, sizeof(struct ip_set *), GFP_KERNEL); + list = kvcalloc(inst->ip_set_max, sizeof(struct ip_set *), GFP_KERNEL); if (!list) return -ENOMEM; inst->is_deleted = false; @@ -2086,7 +2086,7 @@ ip_set_net_exit(struct net *net) } } nfnl_unlock(NFNL_SUBSYS_IPSET); - kfree(rcu_dereference_protected(inst->ip_set_list, 1)); + kvfree(rcu_dereference_protected(inst->ip_set_list, 1)); } static struct pernet_operations ip_set_net_ops = { From patchwork Sat Oct 27 16:05:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jozsef Kadlecsik X-Patchwork-Id: 989913 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=blackhole.kfki.hu Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=blackhole.kfki.hu header.i=@blackhole.kfki.hu header.b="cpG5CTVk"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42j5Lq0JQ0z9sCm for ; Sun, 28 Oct 2018 03:05:55 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728763AbeJ1ArP (ORCPT ); Sat, 27 Oct 2018 20:47:15 -0400 Received: from smtp-out.kfki.hu ([148.6.0.48]:56937 "EHLO smtp-out.kfki.hu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728746AbeJ1ArP (ORCPT ); Sat, 27 Oct 2018 20:47:15 -0400 Received: from localhost (localhost [127.0.0.1]) by smtp2.kfki.hu (Postfix) with ESMTP id 6CA11CC012F; Sat, 27 Oct 2018 18:05:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= blackhole.kfki.hu; h=references:in-reply-to:x-mailer:message-id :date:date:from:from:received:received:received; s=20151130; t= 1540656345; x=1542470746; bh=JEdoHR40dGtpTPbclZqMtHF6uudSMIk/F4f gfJTOVGQ=; b=cpG5CTVk5h9GX/rs1lDVOjEo7llyRsecv+6Ph1wvpfrFeXiBrKl vkgs59D8oSmSTxb+HNuShrYpjrxDS1Ck6nDFEICloOvTB/z9FhmAl5L4UAZHcGBm BXux1TvdkwdMegmpInvn3ZsHdHSwvNvr4tGAKN1RILshWLjrYS/VX6DM= X-Virus-Scanned: Debian amavisd-new at smtp2.kfki.hu Received: from smtp2.kfki.hu ([127.0.0.1]) by localhost (smtp2.kfki.hu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP; Sat, 27 Oct 2018 18:05:45 +0200 (CEST) Received: from blackhole.kfki.hu (blackhole.kfki.hu [148.6.240.2]) by smtp2.kfki.hu (Postfix) with ESMTP id 1F7F4CC0131; Sat, 27 Oct 2018 18:05:44 +0200 (CEST) Received: by blackhole.kfki.hu (Postfix, from userid 1000) id 0D51720709; Sat, 27 Oct 2018 18:05:44 +0200 (CEST) From: Jozsef Kadlecsik To: netfilter-devel@vger.kernel.org Cc: Pablo Neira Ayuso Subject: [PATCH 4/5] netfilter: ipset: Correct rcu_dereference() call in ip_set_put_comment() Date: Sat, 27 Oct 2018 18:05:42 +0200 Message-Id: <1540656343-822-5-git-send-email-kadlec@blackhole.kfki.hu> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1540656343-822-1-git-send-email-kadlec@blackhole.kfki.hu> References: <1540656343-822-1-git-send-email-kadlec@blackhole.kfki.hu> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org The function is called when rcu_read_lock() is held and not when rcu_read_lock_bh() is held. Signed-off-by: Jozsef Kadlecsik --- include/linux/netfilter/ipset/ip_set_comment.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/netfilter/ipset/ip_set_comment.h b/include/linux/netfilter/ipset/ip_set_comment.h index 8e2bab1..70877f8d 100644 --- a/include/linux/netfilter/ipset/ip_set_comment.h +++ b/include/linux/netfilter/ipset/ip_set_comment.h @@ -43,11 +43,11 @@ ip_set_init_comment(struct ip_set *set, struct ip_set_comment *comment, rcu_assign_pointer(comment->c, c); } -/* Used only when dumping a set, protected by rcu_read_lock_bh() */ +/* Used only when dumping a set, protected by rcu_read_lock() */ static inline int ip_set_put_comment(struct sk_buff *skb, const struct ip_set_comment *comment) { - struct ip_set_comment_rcu *c = rcu_dereference_bh(comment->c); + struct ip_set_comment_rcu *c = rcu_dereference(comment->c); if (!c) return 0; From patchwork Sat Oct 27 16:05:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jozsef Kadlecsik X-Patchwork-Id: 989917 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=blackhole.kfki.hu Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=blackhole.kfki.hu header.i=@blackhole.kfki.hu header.b="Gf9MSSNa"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42j5Ls5jZvz9sCm for ; Sun, 28 Oct 2018 03:05:57 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728771AbeJ1ArQ (ORCPT ); Sat, 27 Oct 2018 20:47:16 -0400 Received: from smtp-out.kfki.hu ([148.6.0.48]:38657 "EHLO smtp-out.kfki.hu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728751AbeJ1ArP (ORCPT ); Sat, 27 Oct 2018 20:47:15 -0400 Received: from localhost (localhost [127.0.0.1]) by smtp2.kfki.hu (Postfix) with ESMTP id 0EB96CC0131; Sat, 27 Oct 2018 18:05:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= blackhole.kfki.hu; h=references:in-reply-to:x-mailer:message-id :date:date:from:from:received:received:received; s=20151130; t= 1540656346; x=1542470747; bh=u+Ir1CKrodqqPMHQrfUEBWWH3c9WqwIrJcZ uPyHoVno=; b=Gf9MSSNaWAydbe0wKO0wVZXlOzQHVItIcwvuVqiUCHXzYytECdL fcxQwTOhcQ8vh0GCryWgIcO44C2gYvXnIyDCCDfeyuoQBi8MBYsptgqIdiHHIFxR KkJtXW55GfXrsREXnR/hdEXe9jdbt+16Sza90Cvf+EYE+U6nLkraOdJ8= X-Virus-Scanned: Debian amavisd-new at smtp2.kfki.hu Received: from smtp2.kfki.hu ([127.0.0.1]) by localhost (smtp2.kfki.hu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP; Sat, 27 Oct 2018 18:05:46 +0200 (CEST) Received: from blackhole.kfki.hu (blackhole.szhk.kfki.hu [148.6.240.2]) by smtp2.kfki.hu (Postfix) with ESMTP id 33B0ACC0132; Sat, 27 Oct 2018 18:05:44 +0200 (CEST) Received: by blackhole.kfki.hu (Postfix, from userid 1000) id 24D7920576; Sat, 27 Oct 2018 18:05:44 +0200 (CEST) From: Jozsef Kadlecsik To: netfilter-devel@vger.kernel.org Cc: Pablo Neira Ayuso Subject: [PATCH 5/5] netfilter: ipset: Fix calling ip_set() macro at dumping Date: Sat, 27 Oct 2018 18:05:43 +0200 Message-Id: <1540656343-822-6-git-send-email-kadlec@blackhole.kfki.hu> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1540656343-822-1-git-send-email-kadlec@blackhole.kfki.hu> References: <1540656343-822-1-git-send-email-kadlec@blackhole.kfki.hu> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org The ip_set() macro is called when either ip_set_ref_lock held only or no lock/nfnl mutex is held at dumping. Take this into account properly. Signed-off-by: Jozsef Kadlecsik --- net/netfilter/ipset/ip_set_core.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index 68db946..292f7c7 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c @@ -55,12 +55,27 @@ MODULE_AUTHOR("Jozsef Kadlecsik "); MODULE_DESCRIPTION("core IP set support"); MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_IPSET); -/* When the nfnl mutex is held: */ +/* When the nfnl mutex or ip_set_ref_lock is held: */ #define ip_set_dereference(p) \ - rcu_dereference_protected(p, lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET)) + rcu_dereference_protected(p, \ + lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET) || \ + lockdep_is_held(&ip_set_ref_lock)) #define ip_set(inst, id) \ ip_set_dereference((inst)->ip_set_list)[id] +/* When the nfnl mutex is not held (dumping): */ +static inline +struct ip_set * ip_set_no_mutex(struct ip_set_net *inst, ip_set_id_t id) +{ + struct ip_set *set; + + rcu_read_lock(); + set = rcu_dereference((inst)->ip_set_list)[id]; + rcu_read_unlock(); + + return set; +} + /* The set types are implemented in modules and registered set types * can be found in ip_set_type_list. Adding/deleting types is * serialized by ip_set_type_mutex. @@ -1251,7 +1266,7 @@ ip_set_dump_done(struct netlink_callback *cb) struct ip_set_net *inst = (struct ip_set_net *)cb->args[IPSET_CB_NET]; ip_set_id_t index = (ip_set_id_t)cb->args[IPSET_CB_INDEX]; - struct ip_set *set = ip_set(inst, index); + struct ip_set *set = ip_set_no_mutex(inst, index); if (set->variant->uref) set->variant->uref(set, cb, false); @@ -1440,7 +1455,7 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb) release_refcount: /* If there was an error or set is done, release set */ if (ret || !cb->args[IPSET_CB_ARG0]) { - set = ip_set(inst, index); + set = ip_set_no_mutex(inst, index); if (set->variant->uref) set->variant->uref(set, cb, false); pr_debug("release set %s\n", set->name);