aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-08-11 13:26:15 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-11 13:26:15 -0400
commitf00439e2e34e97130981c8b68310b8b77b86645a (patch)
treeabe3e3f66713d6e80f4c4b9fa774117947af556a
parent4da5e6a01315fe2a6bc47fe9b076168141c9d9aa (diff)
parent609ccf087747de48ef52160f93e0df864c532a61 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains fixes for your net tree, they are: 1) Unitialize the set element key and data from the commit path, otherwise this leaks chain refcount if the transaction is aborted, reported by Thomas Graf. 2) Fix crash when updating chains without no counters in nf_tables, this slipped through in the new transaction infrastructure, reported by Matteo Croce. 3) Replace all mutex_lock_interruptible() by mutex_lock() in the Netfilter tree, suggested by Patrick McHardy. This implicitly fixes the problem that Eric Dumazet reported in: http://patchwork.ozlabs.org/patch/373076/ 4) Fix error return code in nf_tables when deleting set element in nf_tables if the transaction cannot be allocated, from Julia Lawall. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/bridge/netfilter/ebtables.c10
-rw-r--r--net/netfilter/core.c11
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c19
-rw-r--r--net/netfilter/nf_sockopt.c8
-rw-r--r--net/netfilter/nf_tables_api.c30
-rw-r--r--net/netfilter/x_tables.c47
6 files changed, 39 insertions, 86 deletions
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 1059ed3bc255..6d69631b9f4d 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -327,10 +327,7 @@ find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
327 char name[EBT_FUNCTION_MAXNAMELEN]; 327 char name[EBT_FUNCTION_MAXNAMELEN];
328 } *e; 328 } *e;
329 329
330 *error = mutex_lock_interruptible(mutex); 330 mutex_lock(mutex);
331 if (*error != 0)
332 return NULL;
333
334 list_for_each_entry(e, head, list) { 331 list_for_each_entry(e, head, list) {
335 if (strcmp(e->name, name) == 0) 332 if (strcmp(e->name, name) == 0)
336 return e; 333 return e;
@@ -1203,10 +1200,7 @@ ebt_register_table(struct net *net, const struct ebt_table *input_table)
1203 1200
1204 table->private = newinfo; 1201 table->private = newinfo;
1205 rwlock_init(&table->lock); 1202 rwlock_init(&table->lock);
1206 ret = mutex_lock_interruptible(&ebt_mutex); 1203 mutex_lock(&ebt_mutex);
1207 if (ret != 0)
1208 goto free_chainstack;
1209
1210 list_for_each_entry(t, &net->xt.tables[NFPROTO_BRIDGE], list) { 1204 list_for_each_entry(t, &net->xt.tables[NFPROTO_BRIDGE], list) {
1211 if (strcmp(t->name, table->name) == 0) { 1205 if (strcmp(t->name, table->name) == 0) {
1212 ret = -EEXIST; 1206 ret = -EEXIST;
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 1fbab0cdd302..a93c97f106d4 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -35,11 +35,7 @@ EXPORT_SYMBOL_GPL(nf_ipv6_ops);
35 35
36int nf_register_afinfo(const struct nf_afinfo *afinfo) 36int nf_register_afinfo(const struct nf_afinfo *afinfo)
37{ 37{
38 int err; 38 mutex_lock(&afinfo_mutex);
39
40 err = mutex_lock_interruptible(&afinfo_mutex);
41 if (err < 0)
42 return err;
43 RCU_INIT_POINTER(nf_afinfo[afinfo->family], afinfo); 39 RCU_INIT_POINTER(nf_afinfo[afinfo->family], afinfo);
44 mutex_unlock(&afinfo_mutex); 40 mutex_unlock(&afinfo_mutex);
45 return 0; 41 return 0;
@@ -68,11 +64,8 @@ static DEFINE_MUTEX(nf_hook_mutex);
68int nf_register_hook(struct nf_hook_ops *reg) 64int nf_register_hook(struct nf_hook_ops *reg)
69{ 65{
70 struct nf_hook_ops *elem; 66 struct nf_hook_ops *elem;
71 int err;
72 67
73 err = mutex_lock_interruptible(&nf_hook_mutex); 68 mutex_lock(&nf_hook_mutex);
74 if (err < 0)
75 return err;
76 list_for_each_entry(elem, &nf_hooks[reg->pf][reg->hooknum], list) { 69 list_for_each_entry(elem, &nf_hooks[reg->pf][reg->hooknum], list) {
77 if (reg->priority < elem->priority) 70 if (reg->priority < elem->priority)
78 break; 71 break;
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 8416307fdd1d..fd3f444a4f96 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -2271,10 +2271,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
2271 cmd == IP_VS_SO_SET_STOPDAEMON) { 2271 cmd == IP_VS_SO_SET_STOPDAEMON) {
2272 struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg; 2272 struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg;
2273 2273
2274 if (mutex_lock_interruptible(&ipvs->sync_mutex)) { 2274 mutex_lock(&ipvs->sync_mutex);
2275 ret = -ERESTARTSYS;
2276 goto out_dec;
2277 }
2278 if (cmd == IP_VS_SO_SET_STARTDAEMON) 2275 if (cmd == IP_VS_SO_SET_STARTDAEMON)
2279 ret = start_sync_thread(net, dm->state, dm->mcast_ifn, 2276 ret = start_sync_thread(net, dm->state, dm->mcast_ifn,
2280 dm->syncid); 2277 dm->syncid);
@@ -2284,11 +2281,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
2284 goto out_dec; 2281 goto out_dec;
2285 } 2282 }
2286 2283
2287 if (mutex_lock_interruptible(&__ip_vs_mutex)) { 2284 mutex_lock(&__ip_vs_mutex);
2288 ret = -ERESTARTSYS;
2289 goto out_dec;
2290 }
2291
2292 if (cmd == IP_VS_SO_SET_FLUSH) { 2285 if (cmd == IP_VS_SO_SET_FLUSH) {
2293 /* Flush the virtual service */ 2286 /* Flush the virtual service */
2294 ret = ip_vs_flush(net, false); 2287 ret = ip_vs_flush(net, false);
@@ -2573,9 +2566,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
2573 struct ip_vs_daemon_user d[2]; 2566 struct ip_vs_daemon_user d[2];
2574 2567
2575 memset(&d, 0, sizeof(d)); 2568 memset(&d, 0, sizeof(d));
2576 if (mutex_lock_interruptible(&ipvs->sync_mutex)) 2569 mutex_lock(&ipvs->sync_mutex);
2577 return -ERESTARTSYS;
2578
2579 if (ipvs->sync_state & IP_VS_STATE_MASTER) { 2570 if (ipvs->sync_state & IP_VS_STATE_MASTER) {
2580 d[0].state = IP_VS_STATE_MASTER; 2571 d[0].state = IP_VS_STATE_MASTER;
2581 strlcpy(d[0].mcast_ifn, ipvs->master_mcast_ifn, 2572 strlcpy(d[0].mcast_ifn, ipvs->master_mcast_ifn,
@@ -2594,9 +2585,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
2594 return ret; 2585 return ret;
2595 } 2586 }
2596 2587
2597 if (mutex_lock_interruptible(&__ip_vs_mutex)) 2588 mutex_lock(&__ip_vs_mutex);
2598 return -ERESTARTSYS;
2599
2600 switch (cmd) { 2589 switch (cmd) {
2601 case IP_VS_SO_GET_VERSION: 2590 case IP_VS_SO_GET_VERSION:
2602 { 2591 {
diff --git a/net/netfilter/nf_sockopt.c b/net/netfilter/nf_sockopt.c
index f042ae521557..c68c1e58b362 100644
--- a/net/netfilter/nf_sockopt.c
+++ b/net/netfilter/nf_sockopt.c
@@ -26,9 +26,7 @@ int nf_register_sockopt(struct nf_sockopt_ops *reg)
26 struct nf_sockopt_ops *ops; 26 struct nf_sockopt_ops *ops;
27 int ret = 0; 27 int ret = 0;
28 28
29 if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0) 29 mutex_lock(&nf_sockopt_mutex);
30 return -EINTR;
31
32 list_for_each_entry(ops, &nf_sockopts, list) { 30 list_for_each_entry(ops, &nf_sockopts, list) {
33 if (ops->pf == reg->pf 31 if (ops->pf == reg->pf
34 && (overlap(ops->set_optmin, ops->set_optmax, 32 && (overlap(ops->set_optmin, ops->set_optmax,
@@ -65,9 +63,7 @@ static struct nf_sockopt_ops *nf_sockopt_find(struct sock *sk, u_int8_t pf,
65{ 63{
66 struct nf_sockopt_ops *ops; 64 struct nf_sockopt_ops *ops;
67 65
68 if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0) 66 mutex_lock(&nf_sockopt_mutex);
69 return ERR_PTR(-EINTR);
70
71 list_for_each_entry(ops, &nf_sockopts, list) { 67 list_for_each_entry(ops, &nf_sockopts, list) {
72 if (ops->pf == pf) { 68 if (ops->pf == pf) {
73 if (!try_module_get(ops->owner)) 69 if (!try_module_get(ops->owner))
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index b8035c2d6667..deeb95fb7028 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -899,6 +899,9 @@ static struct nft_stats __percpu *nft_stats_alloc(const struct nlattr *attr)
899static void nft_chain_stats_replace(struct nft_base_chain *chain, 899static void nft_chain_stats_replace(struct nft_base_chain *chain,
900 struct nft_stats __percpu *newstats) 900 struct nft_stats __percpu *newstats)
901{ 901{
902 if (newstats == NULL)
903 return;
904
902 if (chain->stats) { 905 if (chain->stats) {
903 struct nft_stats __percpu *oldstats = 906 struct nft_stats __percpu *oldstats =
904 nft_dereference(chain->stats); 907 nft_dereference(chain->stats);
@@ -3134,16 +3137,13 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
3134 goto err2; 3137 goto err2;
3135 3138
3136 trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set); 3139 trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set);
3137 if (trans == NULL) 3140 if (trans == NULL) {
3141 err = -ENOMEM;
3138 goto err2; 3142 goto err2;
3143 }
3139 3144
3140 nft_trans_elem(trans) = elem; 3145 nft_trans_elem(trans) = elem;
3141 list_add_tail(&trans->list, &ctx->net->nft.commit_li