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;
}

Reply via email to