[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <451d1c63-0d3c-75a5-dea6-4bf2dd8708ca@virtuozzo.com>
Date: Sat, 10 Feb 2018 11:46:50 +0300
From: Kirill Tkhai <ktkhai@...tuozzo.com>
To: pablo@...filter.org,
Linux Kernel Network Developers <netdev@...r.kernel.org>
Subject: Re: [Q] iptables: child user_ns: Fatal: can't open lock file
/run/xtables.lock: Permission denied
On 09.02.2018 16:34, Kirill Tkhai wrote:
> Hi,
>
> after commit 80d8bfaac9e2430d710084a10ec78e68bd61e6ec "iptables: insist that the lock is held."
> it became impossible restore to configure iptables from child user namespace:
>
> kirill@:~/criu$ unshare -U -m -p -f -n --map-root-user --mount-proc
> root@:~/criu# iptables -A INPUT -s 1.2.3.4 -j DROP
> Fatal: can't open lock file /run/xtables.lock: Permission denied
>
> iptables running inside init user ns/init net ns create the file with 0600, and others
> are not able to open it.
>
> It seems a good solution could be to use per net ns file to flock it,
> and this would provide more scalability. But the problem is there is
> not good one to choose. It could be someone like /proc/self/net/netfilter,
> but /proc fs is made in the way, that /proc/X/net/netfilter and /proc/Y/net/netfilter
> have different inodes, despite X and Y refer to the same net ns. It seems,
> the only good candidate is /proc/self/ns/net, but it's too generic file
> to lock it (it may be interesting not only for iptables). Not sure, we can use it.
>
> So, it looks like the solution may be to create the file with 0666 mode by default.
> This does not lose security, as it's only iptables agreement, and evil person
> could just compile iptables without this file lock check. How do you think about all this?
>
> diff --git a/iptables/xshared.c b/iptables/xshared.c
> index 06db72d4..fbbe9495 100644
> --- a/iptables/xshared.c
> +++ b/iptables/xshared.c
> @@ -254,7 +254,7 @@ static int xtables_lock(int wait, struct timeval *wait_interval)
> time_left.tv_sec = wait;
> time_left.tv_usec = 0;
>
> - fd = open(XT_LOCK_NAME, O_CREAT, 0600);
> + fd = open(XT_LOCK_NAME, O_CREAT, 0666);
> if (fd < 0) {
> fprintf(stderr, "Fatal: can't open lock file %s: %s\n",
> XT_LOCK_NAME, strerror(errno));
>
> Kirill
Hm. I've tried "/proc/self/net/netfilter", and found the inodes are identical.
But for some strange reasons it's possible to take flock() twice on it. So we
can't use it till this is not fixed.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int lock_file()
{
struct stat buf;
int fd;
fd = open("/proc/self/net/netfilter", O_RDONLY, 0600);
if (fd < 0) {
perror("Fatal: can't open lock file\n");
return 1;
}
if (flock(fd, LOCK_EX) == 0)
printf("%d: OK\n", getpid());
else
perror("FAIL\n");
return 0;
}
int main()
{
if (fork() == -1) {
perror("fork");
exit(1);
}
lock_file();
sleep(100);
return 0;
}
Powered by blists - more mailing lists