diff options
author | Aaron Conole <aconole@bytheb.org> | 2016-09-28 17:35:15 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2016-09-30 20:15:26 +0200 |
commit | 7816ec564ec40ae20bb7925f733a181cad0cc491 (patch) | |
tree | de2a2b6cd249138f1cb3427126d52716a1df7272 /net | |
parent | netfilter: Fix potential null pointer dereference (diff) | |
download | linux-7816ec564ec40ae20bb7925f733a181cad0cc491.tar.xz linux-7816ec564ec40ae20bb7925f733a181cad0cc491.zip |
netfilter: accommodate different kconfig in nf_set_hooks_head
When CONFIG_NETFILTER_INGRESS is unset (or no), we need to handle
the request for registration properly by dropping the hook. This
releases the entry during the set.
Fixes: e3b37f11e6e4 ("netfilter: replace list_head with single linked list")
Signed-off-by: Aaron Conole <aconole@bytheb.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/core.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/net/netfilter/core.c b/net/netfilter/core.c index e3f68a786afe..c9d90eb64046 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -90,10 +90,12 @@ static void nf_set_hooks_head(struct net *net, const struct nf_hook_ops *reg, { switch (reg->pf) { case NFPROTO_NETDEV: +#ifdef CONFIG_NETFILTER_INGRESS /* We already checked in nf_register_net_hook() that this is * used from ingress. */ rcu_assign_pointer(reg->dev->nf_hooks_ingress, entry); +#endif break; default: rcu_assign_pointer(net->nf.hooks[reg->pf][reg->hooknum], @@ -107,10 +109,15 @@ int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg) struct nf_hook_entry *hooks_entry; struct nf_hook_entry *entry; - if (reg->pf == NFPROTO_NETDEV && - (reg->hooknum != NF_NETDEV_INGRESS || - !reg->dev || dev_net(reg->dev) != net)) - return -EINVAL; + if (reg->pf == NFPROTO_NETDEV) { +#ifndef CONFIG_NETFILTER_INGRESS + if (reg->hooknum == NF_NETDEV_INGRESS) + return -EOPNOTSUPP; +#endif + if (reg->hooknum != NF_NETDEV_INGRESS || + !reg->dev || dev_net(reg->dev) != net) + return -EINVAL; + } entry = kmalloc(sizeof(*entry), GFP_KERNEL); if (!entry) |