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