netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] Netfilter fixes for net
@ 2015-09-18  9:17 Pablo Neira Ayuso
  2015-09-18  9:17 ` [PATCH 1/4] netfilter: nf_log: don't zap all loggers on unregister Pablo Neira Ayuso
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Pablo Neira Ayuso @ 2015-09-18  9:17 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

Hi David,

The following patch contains Netfilter fixes for your net tree, they are:

1) nf_log_unregister() should only set to NULL the logger that is being
   unregistered, instead of everything else. Patch from Florian Westphal.

2) Fix a crash when accessing physoutdev from PREROUTING in br_netfilter.
   This is partially reverting the patch to shrink nf_bridge_info to 32 bytes.
   Also from Florian.

3) Use existing match/target extensions in the internal nft_compat extension
   lists when the extension is family unspecific (ie. NFPROTO_UNSPEC).

4) Wait for rcu grace period before leaving nf_log_unregister().

You can pull these changes from:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git

Thanks!

----------------------------------------------------------------

The following changes since commit e8684c88774c0ddfeefdbed0aa469b25b9962f3e:

  irda: ali-ircc: Fix deadlock in ali_ircc_sir_change_speed() (2015-09-11 16:18:33 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git master

for you to fetch changes up to ad5001cc7cdf9aaee5eb213fdee657e4a3c94776:

  netfilter: nf_log: wait for rcu grace after logger unregistration (2015-09-17 13:37:31 +0200)

----------------------------------------------------------------
Florian Westphal (2):
      netfilter: nf_log: don't zap all loggers on unregister
      netfilter: bridge: fix routing of bridge frames with call-iptables=1

Pablo Neira Ayuso (2):
      netfilter: nft_compat: skip family comparison in case of NFPROTO_UNSPEC
      netfilter: nf_log: wait for rcu grace after logger unregistration

 include/linux/skbuff.h     |    6 +++---
 net/netfilter/nf_log.c     |    9 +++++++--
 net/netfilter/nft_compat.c |   24 ++++++++++++++++++------
 3 files changed, 28 insertions(+), 11 deletions(-)

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] netfilter: nf_log: don't zap all loggers on unregister
  2015-09-18  9:17 [PATCH 0/4] Netfilter fixes for net Pablo Neira Ayuso
@ 2015-09-18  9:17 ` Pablo Neira Ayuso
  2015-09-18  9:17 ` [PATCH 2/4] netfilter: bridge: fix routing of bridge frames with call-iptables=1 Pablo Neira Ayuso
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Pablo Neira Ayuso @ 2015-09-18  9:17 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Florian Westphal <fw@strlen.de>

like nf_log_unset, nf_log_unregister must not reset the list of loggers.
Otherwise, a call to nf_log_unregister() will render loggers of other nf
protocols unusable:

iptables -A INPUT -j LOG
modprobe nf_log_arp ; rmmod nf_log_arp
iptables -A INPUT -j LOG
iptables: No chain/target/match by that name

Fixes: 30e0c6a6be ("netfilter: nf_log: prepare net namespace support for loggers")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_log.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 675d12c..a5ebd7d 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -107,11 +107,15 @@ EXPORT_SYMBOL(nf_log_register);
 
 void nf_log_unregister(struct nf_logger *logger)
 {
+	const struct nf_logger *log;
 	int i;
 
 	mutex_lock(&nf_log_mutex);
-	for (i = 0; i < NFPROTO_NUMPROTO; i++)
-		RCU_INIT_POINTER(loggers[i][logger->type], NULL);
+	for (i = 0; i < NFPROTO_NUMPROTO; i++) {
+		log = nft_log_dereference(loggers[i][logger->type]);
+		if (log == logger)
+			RCU_INIT_POINTER(loggers[i][logger->type], NULL);
+	}
 	mutex_unlock(&nf_log_mutex);
 }
 EXPORT_SYMBOL(nf_log_unregister);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] netfilter: bridge: fix routing of bridge frames with call-iptables=1
  2015-09-18  9:17 [PATCH 0/4] Netfilter fixes for net Pablo Neira Ayuso
  2015-09-18  9:17 ` [PATCH 1/4] netfilter: nf_log: don't zap all loggers on unregister Pablo Neira Ayuso
@ 2015-09-18  9:17 ` Pablo Neira Ayuso
  2015-09-18  9:17 ` [PATCH 3/4] netfilter: nft_compat: skip family comparison in case of NFPROTO_UNSPEC Pablo Neira Ayuso
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Pablo Neira Ayuso @ 2015-09-18  9:17 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Florian Westphal <fw@strlen.de>

We can't re-use the physoutdev storage area.

1.  When using NFQUEUE in PREROUTING, we attempt to bump a bogus
refcnt since nf_bridge->physoutdev is garbage (ipv4/ipv6 address)

2. for same reason, we crash in physdev match in FORWARD or later if
skb is routed instead of bridged.

This increases nf_bridge_info to 40 bytes, but we have no other choice.

Fixes: 72b1e5e4cac7 ("netfilter: bridge: reduce nf_bridge_info to 32 bytes again")
Reported-by: Sander Eikelenboom <linux@eikelenboom.it>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/linux/skbuff.h |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 2738d35..9987af0 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -179,6 +179,9 @@ struct nf_bridge_info {
 	u8			bridged_dnat:1;
 	__u16			frag_max_size;
 	struct net_device	*physindev;
+
+	/* always valid & non-NULL from FORWARD on, for physdev match */
+	struct net_device	*physoutdev;
 	union {
 		/* prerouting: detect dnat in orig/reply direction */
 		__be32          ipv4_daddr;
@@ -189,9 +192,6 @@ struct nf_bridge_info {
 		 * skb is out in neigh layer.
 		 */
 		char neigh_header[8];
-
-		/* always valid & non-NULL from FORWARD on, for physdev match */
-		struct net_device *physoutdev;
 	};
 };
 #endif
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] netfilter: nft_compat: skip family comparison in case of NFPROTO_UNSPEC
  2015-09-18  9:17 [PATCH 0/4] Netfilter fixes for net Pablo Neira Ayuso
  2015-09-18  9:17 ` [PATCH 1/4] netfilter: nf_log: don't zap all loggers on unregister Pablo Neira Ayuso
  2015-09-18  9:17 ` [PATCH 2/4] netfilter: bridge: fix routing of bridge frames with call-iptables=1 Pablo Neira Ayuso
@ 2015-09-18  9:17 ` Pablo Neira Ayuso
  2015-09-18  9:17 ` [PATCH 4/4] netfilter: nf_log: wait for rcu grace after logger unregistration Pablo Neira Ayuso
  2015-09-21  5:32 ` [PATCH 0/4] Netfilter fixes for net David Miller
  4 siblings, 0 replies; 6+ messages in thread
From: Pablo Neira Ayuso @ 2015-09-18  9:17 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

Fix lookup of existing match/target structures in the corresponding list
by skipping the family check if NFPROTO_UNSPEC is used.

This is resulting in the allocation and insertion of one match/target
structure for each use of them. So this not only bloats memory
consumption but also severely affects the time to reload the ruleset
from the iptables-compat utility.

After this patch, iptables-compat-restore and iptables-compat take
almost the same time to reload large rulesets.

Fixes: 0ca743a55991 ("netfilter: nf_tables: add compatibility layer for x_tables")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nft_compat.c |   24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 66def31..9c8fab0 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -619,6 +619,13 @@ struct nft_xt {
 
 static struct nft_expr_type nft_match_type;
 
+static bool nft_match_cmp(const struct xt_match *match,
+			  const char *name, u32 rev, u32 family)
+{
+	return strcmp(match->name, name) == 0 && match->revision == rev &&
+	       (match->family == NFPROTO_UNSPEC || match->family == family);
+}
+
 static const struct nft_expr_ops *
 nft_match_select_ops(const struct nft_ctx *ctx,
 		     const struct nlattr * const tb[])
@@ -626,7 +633,7 @@ nft_match_select_ops(const struct nft_ctx *ctx,
 	struct nft_xt *nft_match;
 	struct xt_match *match;
 	char *mt_name;
-	__u32 rev, family;
+	u32 rev, family;
 
 	if (tb[NFTA_MATCH_NAME] == NULL ||
 	    tb[NFTA_MATCH_REV] == NULL ||
@@ -641,8 +648,7 @@ nft_match_select_ops(const struct nft_ctx *ctx,
 	list_for_each_entry(nft_match, &nft_match_list, head) {
 		struct xt_match *match = nft_match->ops.data;
 
-		if (strcmp(match->name, mt_name) == 0 &&
-		    match->revision == rev && match->family == family) {
+		if (nft_match_cmp(match, mt_name, rev, family)) {
 			if (!try_module_get(match->me))
 				return ERR_PTR(-ENOENT);
 
@@ -693,6 +699,13 @@ static LIST_HEAD(nft_target_list);
 
 static struct nft_expr_type nft_target_type;
 
+static bool nft_target_cmp(const struct xt_target *tg,
+			   const char *name, u32 rev, u32 family)
+{
+	return strcmp(tg->name, name) == 0 && tg->revision == rev &&
+	       (tg->family == NFPROTO_UNSPEC || tg->family == family);
+}
+
 static const struct nft_expr_ops *
 nft_target_select_ops(const struct nft_ctx *ctx,
 		      const struct nlattr * const tb[])
@@ -700,7 +713,7 @@ nft_target_select_ops(const struct nft_ctx *ctx,
 	struct nft_xt *nft_target;
 	struct xt_target *target;
 	char *tg_name;
-	__u32 rev, family;
+	u32 rev, family;
 
 	if (tb[NFTA_TARGET_NAME] == NULL ||
 	    tb[NFTA_TARGET_REV] == NULL ||
@@ -715,8 +728,7 @@ nft_target_select_ops(const struct nft_ctx *ctx,
 	list_for_each_entry(nft_target, &nft_target_list, head) {
 		struct xt_target *target = nft_target->ops.data;
 
-		if (strcmp(target->name, tg_name) == 0 &&
-		    target->revision == rev && target->family == family) {
+		if (nft_target_cmp(target, tg_name, rev, family)) {
 			if (!try_module_get(target->me))
 				return ERR_PTR(-ENOENT);
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] netfilter: nf_log: wait for rcu grace after logger unregistration
  2015-09-18  9:17 [PATCH 0/4] Netfilter fixes for net Pablo Neira Ayuso
                   ` (2 preceding siblings ...)
  2015-09-18  9:17 ` [PATCH 3/4] netfilter: nft_compat: skip family comparison in case of NFPROTO_UNSPEC Pablo Neira Ayuso
@ 2015-09-18  9:17 ` Pablo Neira Ayuso
  2015-09-21  5:32 ` [PATCH 0/4] Netfilter fixes for net David Miller
  4 siblings, 0 replies; 6+ messages in thread
From: Pablo Neira Ayuso @ 2015-09-18  9:17 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

The nf_log_unregister() function needs to call synchronize_rcu() to make sure
that the objects are not dereferenced anymore on module removal.

Fixes: 5962815a6a56 ("netfilter: nf_log: use an array of loggers instead of list")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_log.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index a5ebd7d..a5d41df 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -117,6 +117,7 @@ void nf_log_unregister(struct nf_logger *logger)
 			RCU_INIT_POINTER(loggers[i][logger->type], NULL);
 	}
 	mutex_unlock(&nf_log_mutex);
+	synchronize_rcu();
 }
 EXPORT_SYMBOL(nf_log_unregister);
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] Netfilter fixes for net
  2015-09-18  9:17 [PATCH 0/4] Netfilter fixes for net Pablo Neira Ayuso
                   ` (3 preceding siblings ...)
  2015-09-18  9:17 ` [PATCH 4/4] netfilter: nf_log: wait for rcu grace after logger unregistration Pablo Neira Ayuso
@ 2015-09-21  5:32 ` David Miller
  4 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2015-09-21  5:32 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, netdev

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Fri, 18 Sep 2015 11:17:52 +0200

> The following patch contains Netfilter fixes for your net tree, they are:
> 
> 1) nf_log_unregister() should only set to NULL the logger that is being
>    unregistered, instead of everything else. Patch from Florian Westphal.
> 
> 2) Fix a crash when accessing physoutdev from PREROUTING in br_netfilter.
>    This is partially reverting the patch to shrink nf_bridge_info to 32 bytes.
>    Also from Florian.
> 
> 3) Use existing match/target extensions in the internal nft_compat extension
>    lists when the extension is family unspecific (ie. NFPROTO_UNSPEC).
> 
> 4) Wait for rcu grace period before leaving nf_log_unregister().
> 
> You can pull these changes from:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git

Pulled, thanks Pablo.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-09-21  5:32 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-18  9:17 [PATCH 0/4] Netfilter fixes for net Pablo Neira Ayuso
2015-09-18  9:17 ` [PATCH 1/4] netfilter: nf_log: don't zap all loggers on unregister Pablo Neira Ayuso
2015-09-18  9:17 ` [PATCH 2/4] netfilter: bridge: fix routing of bridge frames with call-iptables=1 Pablo Neira Ayuso
2015-09-18  9:17 ` [PATCH 3/4] netfilter: nft_compat: skip family comparison in case of NFPROTO_UNSPEC Pablo Neira Ayuso
2015-09-18  9:17 ` [PATCH 4/4] netfilter: nf_log: wait for rcu grace after logger unregistration Pablo Neira Ayuso
2015-09-21  5:32 ` [PATCH 0/4] Netfilter fixes for net David Miller

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).