diff options
| author | David S. Miller <[email protected]> | 2014-04-06 11:29:59 -0400 | 
|---|---|---|
| committer | David S. Miller <[email protected]> | 2014-04-06 11:29:59 -0400 | 
| commit | d80e773f16f66a610e04f6875d4da84e74a8fb6c (patch) | |
| tree | 5734eaa39c94ee47fddd8b9077de93c5b0267d0d /net | |
| parent | 00aefceb2fffcf4ea2fbc97ef5d4f79ef2668ecc (diff) | |
| parent | c58dd2dd443c26d856a168db108a0cd11c285bf3 (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says:
====================
The following patchset contains Netfilter fixes for your net tree, they
are:
* Use 16-bits offset and length fields instead of 8-bits in the conntrack
  extension to avoid an overflow when many conntrack extension are used,
  from Andrey Vagin.
* Allow to use cgroup match from LOCAL_IN, there is no apparent reason
  for not allowing this, from Alexey Perevalov.
* Fix build of the connlimit match after recent changes to let it scale
  up that result in a divide by zero compilation error in UP, from
  Florian Westphal.
* Move the lock out of the structure connlimit_data to avoid a false
  sharing spotted by Eric Dumazet and Jesper D. Brouer, this needed as
  part of the recent connlimit scalability improvements, also from
  Florian Westphal.
* Add missing module aliases in xt_osf to fix loading of rules using
  this match, from Kirill Tkhai.
* Restrict set names in nf_tables to 15 characters instead of silently
  trimming them off, from me.
* Fix wrong format in nf_tables request module call for chain types,
  spotted by Florian Westphal, patch from me.
* Fix crash in xtables when it fails to copy the counters back to userspace
  after having replaced the table already.
====================
Signed-off-by: David S. Miller <[email protected]>
Diffstat (limited to 'net')
| -rw-r--r-- | net/bridge/netfilter/ebtables.c | 5 | ||||
| -rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 6 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 6 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 6 | ||||
| -rw-r--r-- | net/netfilter/nf_tables_api.c | 7 | ||||
| -rw-r--r-- | net/netfilter/xt_cgroup.c | 3 | ||||
| -rw-r--r-- | net/netfilter/xt_connlimit.c | 25 | ||||
| -rw-r--r-- | net/netfilter/xt_osf.c | 2 | 
8 files changed, 38 insertions, 22 deletions
| diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 0e474b13463b..1059ed3bc255 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -1044,10 +1044,9 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl,  	if (repl->num_counters &&  	   copy_to_user(repl->counters, counterstmp,  	   repl->num_counters * sizeof(struct ebt_counter))) { -		ret = -EFAULT; +		/* Silent error, can't fail, new table is already in place */ +		net_warn_ratelimited("ebtables: counters copy to user failed while replacing table\n");  	} -	else -		ret = 0;  	/* decrease module count and free resources */  	EBT_ENTRY_ITERATE(table->entries, table->entries_size, diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 59da7cde0724..f95b6f93814b 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -1044,8 +1044,10 @@ static int __do_replace(struct net *net, const char *name,  	xt_free_table_info(oldinfo);  	if (copy_to_user(counters_ptr, counters, -			 sizeof(struct xt_counters) * num_counters) != 0) -		ret = -EFAULT; +			 sizeof(struct xt_counters) * num_counters) != 0) { +		/* Silent error, can't fail, new table is already in place */ +		net_warn_ratelimited("arptables: counters copy to user failed while replacing table\n"); +	}  	vfree(counters);  	xt_table_unlock(t);  	return ret; diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 718dfbd30cbe..99e810f84671 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1231,8 +1231,10 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,  	xt_free_table_info(oldinfo);  	if (copy_to_user(counters_ptr, counters, -			 sizeof(struct xt_counters) * num_counters) != 0) -		ret = -EFAULT; +			 sizeof(struct xt_counters) * num_counters) != 0) { +		/* Silent error, can't fail, new table is already in place */ +		net_warn_ratelimited("iptables: counters copy to user failed while replacing table\n"); +	}  	vfree(counters);  	xt_table_unlock(t);  	return ret; diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 710238f58aa9..e080fbbbc0e5 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1241,8 +1241,10 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,  	xt_free_table_info(oldinfo);  	if (copy_to_user(counters_ptr, counters, -			 sizeof(struct xt_counters) * num_counters) != 0) -		ret = -EFAULT; +			 sizeof(struct xt_counters) * num_counters) != 0) { +		/* Silent error, can't fail, new table is already in place */ +		net_warn_ratelimited("ip6tables: counters copy to user failed while replacing table\n"); +	}  	vfree(counters);  	xt_table_unlock(t);  	return ret; diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 33045a562297..3fd159db9f06 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -152,8 +152,8 @@ nf_tables_chain_type_lookup(const struct nft_af_info *afi,  #ifdef CONFIG_MODULES  	if (autoload) {  		nfnl_unlock(NFNL_SUBSYS_NFTABLES); -		request_module("nft-chain-%u-%*.s", afi->family, -			       nla_len(nla)-1, (const char *)nla_data(nla)); +		request_module("nft-chain-%u-%.*s", afi->family, +			       nla_len(nla), (const char *)nla_data(nla));  		nfnl_lock(NFNL_SUBSYS_NFTABLES);  		type = __nf_tables_chain_type_lookup(afi->family, nla);  		if (type != NULL) @@ -1946,7 +1946,8 @@ static const struct nft_set_ops *nft_select_set_ops(const struct nlattr * const  static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = {  	[NFTA_SET_TABLE]		= { .type = NLA_STRING }, -	[NFTA_SET_NAME]			= { .type = NLA_STRING }, +	[NFTA_SET_NAME]			= { .type = NLA_STRING, +					    .len = IFNAMSIZ - 1 },  	[NFTA_SET_FLAGS]		= { .type = NLA_U32 },  	[NFTA_SET_KEY_TYPE]		= { .type = NLA_U32 },  	[NFTA_SET_KEY_LEN]		= { .type = NLA_U32 }, diff --git a/net/netfilter/xt_cgroup.c b/net/netfilter/xt_cgroup.c index 9a8e77e7f8d4..f4e833005320 100644 --- a/net/netfilter/xt_cgroup.c +++ b/net/netfilter/xt_cgroup.c @@ -54,7 +54,8 @@ static struct xt_match cgroup_mt_reg __read_mostly = {  	.matchsize  = sizeof(struct xt_cgroup_info),  	.me         = THIS_MODULE,  	.hooks      = (1 << NF_INET_LOCAL_OUT) | -		      (1 << NF_INET_POST_ROUTING), +		      (1 << NF_INET_POST_ROUTING) | +		      (1 << NF_INET_LOCAL_IN),  };  static int __init cgroup_mt_init(void) diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index 458464e7bd7a..fbc66bb250d5 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c @@ -32,8 +32,14 @@  #include <net/netfilter/nf_conntrack_tuple.h>  #include <net/netfilter/nf_conntrack_zones.h> -#define CONNLIMIT_SLOTS		32 -#define CONNLIMIT_LOCK_SLOTS	32 +#define CONNLIMIT_SLOTS		256U + +#ifdef CONFIG_LOCKDEP +#define CONNLIMIT_LOCK_SLOTS	8U +#else +#define CONNLIMIT_LOCK_SLOTS	256U +#endif +  #define CONNLIMIT_GC_MAX_NODES	8  /* we will save the tuples of all connections we care about */ @@ -49,10 +55,11 @@ struct xt_connlimit_rb {  	union nf_inet_addr addr; /* search key */  }; +static spinlock_t xt_connlimit_locks[CONNLIMIT_LOCK_SLOTS] __cacheline_aligned_in_smp; +  struct xt_connlimit_data {  	struct rb_root climit_root4[CONNLIMIT_SLOTS];  	struct rb_root climit_root6[CONNLIMIT_SLOTS]; -	spinlock_t		locks[CONNLIMIT_LOCK_SLOTS];  };  static u_int32_t connlimit_rnd __read_mostly; @@ -297,11 +304,11 @@ static int count_them(struct net *net,  		root = &data->climit_root4[hash];  	} -	spin_lock_bh(&data->locks[hash % CONNLIMIT_LOCK_SLOTS]); +	spin_lock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]);  	count = count_tree(net, root, tuple, addr, mask, family); -	spin_unlock_bh(&data->locks[hash % CONNLIMIT_LOCK_SLOTS]); +	spin_unlock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]);  	return count;  } @@ -377,9 +384,6 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par)  		return -ENOMEM;  	} -	for (i = 0; i < ARRAY_SIZE(info->data->locks); ++i) -		spin_lock_init(&info->data->locks[i]); -  	for (i = 0; i < ARRAY_SIZE(info->data->climit_root4); ++i)  		info->data->climit_root4[i] = RB_ROOT;  	for (i = 0; i < ARRAY_SIZE(info->data->climit_root6); ++i) @@ -435,11 +439,14 @@ static struct xt_match connlimit_mt_reg __read_mostly = {  static int __init connlimit_mt_init(void)  { -	int ret; +	int ret, i;  	BUILD_BUG_ON(CONNLIMIT_LOCK_SLOTS > CONNLIMIT_SLOTS);  	BUILD_BUG_ON((CONNLIMIT_SLOTS % CONNLIMIT_LOCK_SLOTS) != 0); +	for (i = 0; i < CONNLIMIT_LOCK_SLOTS; ++i) +		spin_lock_init(&xt_connlimit_locks[i]); +  	connlimit_conn_cachep = kmem_cache_create("xt_connlimit_conn",  					   sizeof(struct xt_connlimit_conn),  					   0, 0, NULL); diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c index 7174611bd672..c529161cdbf8 100644 --- a/net/netfilter/xt_osf.c +++ b/net/netfilter/xt_osf.c @@ -422,4 +422,6 @@ module_exit(xt_osf_fini);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Evgeniy Polyakov <[email protected]>");  MODULE_DESCRIPTION("Passive OS fingerprint matching."); +MODULE_ALIAS("ipt_osf"); +MODULE_ALIAS("ip6t_osf");  MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_OSF); |