netfilter: call nf_hook_state_init with rcu_read_lock held
authorFlorian Westphal <fw@strlen.de>
Wed, 21 Sep 2016 15:35:02 +0000 (11:35 -0400)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sat, 24 Sep 2016 19:25:49 +0000 (21:25 +0200)
This makes things simpler because we can store the head of the list
in the nf_state structure without worrying about concurrent add/delete
of hook elements from the list.

A future commit will make use of this to implement a simpler
linked-list.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Aaron Conole <aconole@bytheb.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/linux/netfilter.h
include/linux/netfilter_ingress.h

index 9230f9a..ad444f0 100644 (file)
@@ -174,10 +174,16 @@ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
 
        if (!list_empty(hook_list)) {
                struct nf_hook_state state;
+               int ret;
 
+               /* We may already have this, but read-locks nest anyway */
+               rcu_read_lock();
                nf_hook_state_init(&state, hook_list, hook, thresh,
                                   pf, indev, outdev, sk, net, okfn);
-               return nf_hook_slow(skb, &state);
+
+               ret = nf_hook_slow(skb, &state);
+               rcu_read_unlock();
+               return ret;
        }
        return 1;
 }
index 5fcd375..6965ba0 100644 (file)
@@ -14,6 +14,7 @@ static inline bool nf_hook_ingress_active(const struct sk_buff *skb)
        return !list_empty(&skb->dev->nf_hooks_ingress);
 }
 
+/* caller must hold rcu_read_lock */
 static inline int nf_hook_ingress(struct sk_buff *skb)
 {
        struct nf_hook_state state;