Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
authorDavid S. Miller <davem@davemloft.net>
Thu, 6 Oct 2016 00:15:55 +0000 (20:15 -0400)
committerDavid S. Miller <davem@davemloft.net>
Thu, 6 Oct 2016 00:15:55 +0000 (20:15 -0400)
Pablo Neira Ayuso says:

====================
Netfilter fixes for net-next

This is a pull request to address fallout from previous nf-next pull
request, only fixes going on here:

1) Address a potential null dereference in nf_unregister_net_hook()
   when becomes nf_hook_entry_head is NULL, from Aaron Conole.

2) Missing ifdef for CONFIG_NETFILTER_INGRESS, also from Aaron.

3) Fix linking problems in xt_hashlimit in x86_32, from Pai.

4) Fix permissions of nf_log sysctl from unpriviledge netns, from
   Jann Horn.

5) Fix possible divide by zero in nft_limit, from Liping Zhang.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
net/netfilter/core.c
net/netfilter/nf_log.c
net/netfilter/nft_limit.c
net/netfilter/xt_hashlimit.c

index fa6715d..c9d90eb 100644 (file)
@@ -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)
@@ -160,7 +167,7 @@ void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)
 
        mutex_lock(&nf_hook_mutex);
        hooks_entry = nf_hook_entry_head(net, reg);
-       if (hooks_entry->orig_ops == reg) {
+       if (hooks_entry && hooks_entry->orig_ops == reg) {
                nf_set_hooks_head(net, reg,
                                  nf_entry_dereference(hooks_entry->next));
                goto unlock;
index 30a17d6..3dca90d 100644 (file)
@@ -422,7 +422,7 @@ static int nf_log_proc_dostring(struct ctl_table *table, int write,
        char buf[NFLOGGER_NAME_LEN];
        int r = 0;
        int tindex = (unsigned long)table->extra1;
-       struct net *net = current->nsproxy->net_ns;
+       struct net *net = table->extra2;
 
        if (write) {
                struct ctl_table tmp = *table;
@@ -476,7 +476,6 @@ static int netfilter_log_sysctl_init(struct net *net)
                                 3, "%d", i);
                        nf_log_sysctl_table[i].procname =
                                nf_log_sysctl_fnames[i];
-                       nf_log_sysctl_table[i].data = NULL;
                        nf_log_sysctl_table[i].maxlen = NFLOGGER_NAME_LEN;
                        nf_log_sysctl_table[i].mode = 0644;
                        nf_log_sysctl_table[i].proc_handler =
@@ -486,6 +485,9 @@ static int netfilter_log_sysctl_init(struct net *net)
                }
        }
 
+       for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
+               table[i].extra2 = net;
+
        net->nf.nf_log_dir_header = register_net_sysctl(net,
                                                "net/netfilter/nf_log",
                                                table);
index 070b989..c6baf41 100644 (file)
@@ -145,7 +145,7 @@ static int nft_limit_pkts_init(const struct nft_ctx *ctx,
        if (err < 0)
                return err;
 
-       priv->cost = div_u64(priv->limit.nsecs, priv->limit.rate);
+       priv->cost = div64_u64(priv->limit.nsecs, priv->limit.rate);
        return 0;
 }
 
@@ -170,7 +170,7 @@ static void nft_limit_pkt_bytes_eval(const struct nft_expr *expr,
                                     const struct nft_pktinfo *pkt)
 {
        struct nft_limit *priv = nft_expr_priv(expr);
-       u64 cost = div_u64(priv->nsecs * pkt->skb->len, priv->rate);
+       u64 cost = div64_u64(priv->nsecs * pkt->skb->len, priv->rate);
 
        if (nft_limit_eval(priv, cost))
                regs->verdict.code = NFT_BREAK;
index 44a095e..2fab0c6 100644 (file)
@@ -467,17 +467,18 @@ static u64 user2credits(u64 user, int revision)
                /* If multiplying would overflow... */
                if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY_v1))
                        /* Divide first. */
-                       return (user / XT_HASHLIMIT_SCALE) *\
-                                               HZ * CREDITS_PER_JIFFY_v1;
+                       return div64_u64(user, XT_HASHLIMIT_SCALE)
+                               * HZ * CREDITS_PER_JIFFY_v1;
 
-               return (user * HZ * CREDITS_PER_JIFFY_v1) \
-                                               / XT_HASHLIMIT_SCALE;
+               return div64_u64(user * HZ * CREDITS_PER_JIFFY_v1,
+                                XT_HASHLIMIT_SCALE);
        } else {
                if (user > 0xFFFFFFFFFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
-                       return (user / XT_HASHLIMIT_SCALE_v2) *\
-                                               HZ * CREDITS_PER_JIFFY;
+                       return div64_u64(user, XT_HASHLIMIT_SCALE_v2)
+                               * HZ * CREDITS_PER_JIFFY;
 
-               return (user * HZ * CREDITS_PER_JIFFY) / XT_HASHLIMIT_SCALE_v2;
+               return div64_u64(user * HZ * CREDITS_PER_JIFFY,
+                                XT_HASHLIMIT_SCALE_v2);
        }
 }