netfilter: don't use mutex_lock_interruptible()
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 31 Jul 2014 18:38:46 +0000 (20:38 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 8 Aug 2014 14:47:23 +0000 (16:47 +0200)
Eric Dumazet reports that getsockopt() or setsockopt() sometimes
returns -EINTR instead of -ENOPROTOOPT, causing headaches to
application developers.

This patch replaces all the mutex_lock_interruptible() by mutex_lock()
in the netfilter tree, as there is no reason we should sleep for a
long time there.

Reported-by: Eric Dumazet <edumazet@google.com>
Suggested-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Acked-by: Julian Anastasov <ja@ssi.bg>
net/bridge/netfilter/ebtables.c
net/netfilter/core.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/nf_sockopt.c
net/netfilter/x_tables.c

index 1059ed3bc2557d597cb0548962a888e544d74a67..6d69631b9f4d2bf5c667d1f76e4f5bc384cdf61c 100644 (file)
@@ -327,10 +327,7 @@ find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
                char name[EBT_FUNCTION_MAXNAMELEN];
        } *e;
 
-       *error = mutex_lock_interruptible(mutex);
-       if (*error != 0)
-               return NULL;
-
+       mutex_lock(mutex);
        list_for_each_entry(e, head, list) {
                if (strcmp(e->name, name) == 0)
                        return e;
@@ -1203,10 +1200,7 @@ ebt_register_table(struct net *net, const struct ebt_table *input_table)
 
        table->private = newinfo;
        rwlock_init(&table->lock);
-       ret = mutex_lock_interruptible(&ebt_mutex);
-       if (ret != 0)
-               goto free_chainstack;
-
+       mutex_lock(&ebt_mutex);
        list_for_each_entry(t, &net->xt.tables[NFPROTO_BRIDGE], list) {
                if (strcmp(t->name, table->name) == 0) {
                        ret = -EEXIST;
index 1fbab0cdd302bdafe199d434fc10f2f6401ef6a8..a93c97f106d4a5022cd0e1196ee70ecdfd8c2873 100644 (file)
@@ -35,11 +35,7 @@ EXPORT_SYMBOL_GPL(nf_ipv6_ops);
 
 int nf_register_afinfo(const struct nf_afinfo *afinfo)
 {
-       int err;
-
-       err = mutex_lock_interruptible(&afinfo_mutex);
-       if (err < 0)
-               return err;
+       mutex_lock(&afinfo_mutex);
        RCU_INIT_POINTER(nf_afinfo[afinfo->family], afinfo);
        mutex_unlock(&afinfo_mutex);
        return 0;
@@ -68,11 +64,8 @@ static DEFINE_MUTEX(nf_hook_mutex);
 int nf_register_hook(struct nf_hook_ops *reg)
 {
        struct nf_hook_ops *elem;
-       int err;
 
-       err = mutex_lock_interruptible(&nf_hook_mutex);
-       if (err < 0)
-               return err;
+       mutex_lock(&nf_hook_mutex);
        list_for_each_entry(elem, &nf_hooks[reg->pf][reg->hooknum], list) {
                if (reg->priority < elem->priority)
                        break;
index 8416307fdd1d431e5f306efdedaf8682c36fa62b..fd3f444a4f964428ae7290ba337384cf08d6028a 100644 (file)
@@ -2271,10 +2271,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
            cmd == IP_VS_SO_SET_STOPDAEMON) {
                struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg;
 
-               if (mutex_lock_interruptible(&ipvs->sync_mutex)) {
-                       ret = -ERESTARTSYS;
-                       goto out_dec;
-               }
+               mutex_lock(&ipvs->sync_mutex);
                if (cmd == IP_VS_SO_SET_STARTDAEMON)
                        ret = start_sync_thread(net, dm->state, dm->mcast_ifn,
                                                dm->syncid);
@@ -2284,11 +2281,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
                goto out_dec;
        }
 
-       if (mutex_lock_interruptible(&__ip_vs_mutex)) {
-               ret = -ERESTARTSYS;
-               goto out_dec;
-       }
-
+       mutex_lock(&__ip_vs_mutex);
        if (cmd == IP_VS_SO_SET_FLUSH) {
                /* Flush the virtual service */
                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)
                struct ip_vs_daemon_user d[2];
 
                memset(&d, 0, sizeof(d));
-               if (mutex_lock_interruptible(&ipvs->sync_mutex))
-                       return -ERESTARTSYS;
-
+               mutex_lock(&ipvs->sync_mutex);
                if (ipvs->sync_state & IP_VS_STATE_MASTER) {
                        d[0].state = IP_VS_STATE_MASTER;
                        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)
                return ret;
        }
 
-       if (mutex_lock_interruptible(&__ip_vs_mutex))
-               return -ERESTARTSYS;
-
+       mutex_lock(&__ip_vs_mutex);
        switch (cmd) {
        case IP_VS_SO_GET_VERSION:
        {
index f042ae521557b340be5252aa41ccdc67f5202a29..c68c1e58b3628930495c5fe5a24f00f15adc1537 100644 (file)
@@ -26,9 +26,7 @@ int nf_register_sockopt(struct nf_sockopt_ops *reg)
        struct nf_sockopt_ops *ops;
        int ret = 0;
 
-       if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
-               return -EINTR;
-
+       mutex_lock(&nf_sockopt_mutex);
        list_for_each_entry(ops, &nf_sockopts, list) {
                if (ops->pf == reg->pf
                    && (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,
 {
        struct nf_sockopt_ops *ops;
 
-       if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
-               return ERR_PTR(-EINTR);
-
+       mutex_lock(&nf_sockopt_mutex);
        list_for_each_entry(ops, &nf_sockopts, list) {
                if (ops->pf == pf) {
                        if (!try_module_get(ops->owner))
index 47b978bc310039626232525ee08849df56e909ca..272ae4d6fdf4f1dcb27eb2bc6e68414a25b63363 100644 (file)
@@ -71,18 +71,14 @@ static const char *const xt_prefix[NFPROTO_NUMPROTO] = {
 static const unsigned int xt_jumpstack_multiplier = 2;
 
 /* Registration hooks for targets. */
-int
-xt_register_target(struct xt_target *target)
+int xt_register_target(struct xt_target *target)
 {
        u_int8_t af = target->family;
-       int ret;
 
-       ret = mutex_lock_interruptible(&xt[af].mutex);
-       if (ret != 0)
-               return ret;
+       mutex_lock(&xt[af].mutex);
        list_add(&target->list, &xt[af].target);
        mutex_unlock(&xt[af].mutex);
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL(xt_register_target);
 
@@ -125,20 +121,14 @@ xt_unregister_targets(struct xt_target *target, unsigned int n)
 }
 EXPORT_SYMBOL(xt_unregister_targets);
 
-int
-xt_register_match(struct xt_match *match)
+int xt_register_match(struct xt_match *match)
 {
        u_int8_t af = match->family;
-       int ret;
-
-       ret = mutex_lock_interruptible(&xt[af].mutex);
-       if (ret != 0)
-               return ret;
 
+       mutex_lock(&xt[af].mutex);
        list_add(&match->list, &xt[af].match);
        mutex_unlock(&xt[af].mutex);
-
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL(xt_register_match);
 
@@ -194,9 +184,7 @@ struct xt_match *xt_find_match(u8 af, const char *name, u8 revision)
        struct xt_match *m;
        int err = -ENOENT;
 
-       if (mutex_lock_interruptible(&xt[af].mutex) != 0)
-               return ERR_PTR(-EINTR);
-
+       mutex_lock(&xt[af].mutex);
        list_for_each_entry(m, &xt[af].match, list) {
                if (strcmp(m->name, name) == 0) {
                        if (m->revision == revision) {
@@ -239,9 +227,7 @@ struct xt_target *xt_find_target(u8 af, const char *name, u8 revision)
        struct xt_target *t;
        int err = -ENOENT;
 
-       if (mutex_lock_interruptible(&xt[af].mutex) != 0)
-               return ERR_PTR(-EINTR);
-
+       mutex_lock(&xt[af].mutex);
        list_for_each_entry(t, &xt[af].target, list) {
                if (strcmp(t->name, name) == 0) {
                        if (t->revision == revision) {
@@ -323,10 +309,7 @@ int xt_find_revision(u8 af, const char *name, u8 revision, int target,
 {
        int have_rev, best = -1;
 
-       if (mutex_lock_interruptible(&xt[af].mutex) != 0) {
-               *err = -EINTR;
-               return 1;
-       }
+       mutex_lock(&xt[af].mutex);
        if (target == 1)
                have_rev = target_revfn(af, name, revision, &best);
        else
@@ -732,9 +715,7 @@ struct xt_table *xt_find_table_lock(struct net *net, u_int8_t af,
 {
        struct xt_table *t;
 
-       if (mutex_lock_interruptible(&xt[af].mutex) != 0)
-               return ERR_PTR(-EINTR);
-
+       mutex_lock(&xt[af].mutex);
        list_for_each_entry(t, &net->xt.tables[af], list)
                if (strcmp(t->name, name) == 0 && try_module_get(t->me))
                        return t;
@@ -883,10 +864,7 @@ struct xt_table *xt_register_table(struct net *net,
                goto out;
        }
 
-       ret = mutex_lock_interruptible(&xt[table->af].mutex);
-       if (ret != 0)
-               goto out_free;
-
+       mutex_lock(&xt[table->af].mutex);
        /* Don't autoload: we'd eat our tail... */
        list_for_each_entry(t, &net->xt.tables[table->af], list) {
                if (strcmp(t->name, table->name) == 0) {
@@ -911,9 +889,8 @@ struct xt_table *xt_register_table(struct net *net,
        mutex_unlock(&xt[table->af].mutex);
        return table;
 
- unlock:
+unlock:
        mutex_unlock(&xt[table->af].mutex);
-out_free:
        kfree(table);
 out:
        return ERR_PTR(ret);