netfilter: do not propagate nf_queue errors in nf_hook_slow
authorFlorian Westphal <fw@strlen.de>
Mon, 31 Oct 2011 11:20:16 +0000 (12:20 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 1 Nov 2011 08:57:21 +0000 (09:57 +0100)
commit f15850861860636c905b33a9a5be3dcbc2b0d56a
(netfilter: nfnetlink_queue: return error number to caller)
erronously assigns the return value of nf_queue() to the "ret" value.

This can cause bogus return values if we encounter QUEUE verdict
when bypassing is enabled, the listener does not exist and the
next hook returns NF_STOLEN.

In this case nf_hook_slow returned -ESRCH instead of 0.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/core.c

index 3346829..afca6c7 100644 (file)
@@ -180,17 +180,16 @@ next_hook:
                if (ret == 0)
                        ret = -EPERM;
        } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
-               ret = nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
-                              verdict >> NF_VERDICT_QBITS);
-               if (ret < 0) {
-                       if (ret == -ECANCELED)
+               int err = nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
+                                               verdict >> NF_VERDICT_QBITS);
+               if (err < 0) {
+                       if (err == -ECANCELED)
                                goto next_hook;
-                       if (ret == -ESRCH &&
+                       if (err == -ESRCH &&
                           (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
                                goto next_hook;
                        kfree_skb(skb);
                }
-               ret = 0;
        }
        rcu_read_unlock();
        return ret;