From 3046da4bab1b75d1537d76d2c5fd440677b5e114 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Fri, 18 Mar 2016 16:52:40 +0100 Subject: [PATCH] tests/integration: mount /proc in namespaces Because of the use of a PID namespace, we must mount /proc into the appropriate namespace. We don't do that directly when creating namespaces as clone() doesn't account for the namespace change with setns() when we are still in the same process. We also fork a process to do the mount as it seems mount() doesn't get that we are in a different mount namespace either. Obviously, setns() has some drawbacks we need to workaround. We also mount /proc in the chroot. It's absolutely not safe to do so, but that's only for address sanitizer to work as expected. --- tests/integration/fixtures/programs.py | 29 ++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/integration/fixtures/programs.py b/tests/integration/fixtures/programs.py index 39010426..bfb0900d 100644 --- a/tests/integration/fixtures/programs.py +++ b/tests/integration/fixtures/programs.py @@ -43,6 +43,31 @@ def mount_tmpfs(target, private=False): raise OSError(e, os.strerror(e)) +def _mount_proc(target): + flags = [2 | 4 | 8] # MS_NOSUID | MS_NODEV | MS_NOEXEC + flags.append(1 << 18) # MS_PRIVATE + flags.append(1 << 19) # MS_SLAVE + for fl in flags: + ret = libc.mount(b"proc", + target.encode('ascii'), + b"proc", + fl, + None) + if ret == -1: + e = ctypes.get_errno() + raise OSError(e, os.strerror(e)) + + +def mount_proc(target="/proc"): + # We need to be sure /proc is correct. We do that in another + # process as this doesn't play well with setns(). + if not os.path.isdir(target): + os.mkdir(target) + p = multiprocessing.Process(target=_mount_proc, args=(target,)) + p.start() + p.join() + + def most_recent(*args): """Return the most recent files matching one of the provided glob expression.""" @@ -153,6 +178,7 @@ class LldpdFactory(object): # Setup privsep. While not enforced, we assume we are running in a # throwaway mount namespace. tmpdir = self.tmpdir + mount_proc() if self.config.lldpd.privsep.enabled: # Chroot chroot = self.config.lldpd.privsep.chroot @@ -162,6 +188,9 @@ class LldpdFactory(object): parent = os.path.abspath(os.path.join(chroot, os.pardir)) assert os.path.isdir(parent) mount_tmpfs(parent) + if not os.path.isdir(chroot): + os.mkdir(chroot) + mount_proc(os.path.join(chroot, "proc")) # User/group user = self.config.lldpd.privsep.user group = self.config.lldpd.privsep.group -- 2.39.5