diff options
-rwxr-xr-x | examples/chrootfuse.py | 2 | ||||
-rwxr-xr-x | examples/chroottar.py | 2 | ||||
-rwxr-xr-x | examples/userchroot.py | 2 | ||||
-rw-r--r-- | linuxnamespaces/__init__.py | 16 | ||||
-rw-r--r-- | tests/test_simple.py | 2 |
5 files changed, 15 insertions, 9 deletions
diff --git a/examples/chrootfuse.py b/examples/chrootfuse.py index 7e79a2e..d8ca965 100755 --- a/examples/chrootfuse.py +++ b/examples/chrootfuse.py @@ -85,7 +85,7 @@ def main() -> None: os.chdir("/mnt") linuxnamespaces.bind_mount("/proc", "proc", recursive=True) linuxnamespaces.bind_mount("/sys", "sys", recursive=True) - linuxnamespaces.populate_dev("/", ".", pidns=False, tun=False) + linuxnamespaces.populate_dev("/", ".", pts="host", tun=False) if readonly: linuxnamespaces.mount( "tmpfs", "tmp", "tmpfs", linuxnamespaces.MountFlags.NODEV diff --git a/examples/chroottar.py b/examples/chroottar.py index 42c09ef..cf0f87e 100755 --- a/examples/chroottar.py +++ b/examples/chroottar.py @@ -83,7 +83,7 @@ def main() -> None: os.chdir("/mnt") linuxnamespaces.bind_mount("/proc", "proc", recursive=True) linuxnamespaces.bind_mount("/sys", "sys", recursive=True) - linuxnamespaces.populate_dev("/", ".", pidns=False, tun=False) + linuxnamespaces.populate_dev("/", ".", pts="host", tun=False) linuxnamespaces.pivot_root(".", ".") linuxnamespaces.umount(".", linuxnamespaces.UmountFlags.DETACH) if args.command: diff --git a/examples/userchroot.py b/examples/userchroot.py index 2caea33..4006dc6 100755 --- a/examples/userchroot.py +++ b/examples/userchroot.py @@ -39,7 +39,7 @@ def main() -> None: linuxnamespaces.bind_mount(chrootdir, "/mnt", recursive=True) linuxnamespaces.bind_mount("/proc", "/mnt/proc", recursive=True) linuxnamespaces.bind_mount("/sys", "/mnt/sys", recursive=True) - linuxnamespaces.populate_dev("/", "/mnt", pidns=False) + linuxnamespaces.populate_dev("/", "/mnt", pts="host") os.chdir("/mnt") linuxnamespaces.pivot_root(".", ".") linuxnamespaces.umount(".", linuxnamespaces.UmountFlags.DETACH) diff --git a/linuxnamespaces/__init__.py b/linuxnamespaces/__init__.py index a1f790e..83358b6 100644 --- a/linuxnamespaces/__init__.py +++ b/linuxnamespaces/__init__.py @@ -245,7 +245,7 @@ def populate_dev( newroot: PathConvertible, *, fuse: bool = True, - pidns: bool = True, + pts: typing.Literal["defer", "host", "new", "absent"] = "new", tun: bool = True, ) -> None: """Mount a tmpfs to the dev directory beneath newroot and populate it with @@ -255,6 +255,12 @@ def populate_dev( Even though a CAP_SYS_ADMIN-enabled process can umount components of the /dev hierarchy, they they cannot gain privileges in doing so as no hierarchies are restricted via tmpfs mounts or read-only bind mounts. + + The /dev/fuse and /dev/net/tun devices are optional and can be enabled or + disabled as desired. /dev/pts (and /dev/ptmx) can be shared with the host + or mounted as a new instance. Since a PID namespace is usually required for + mounting a new instance, it can also be deferred to a later manual mount. + If not desired, it can be left absent. """ origdev = AtLocation(origroot) / "dev" newdev = AtLocation(newroot) / "dev" @@ -278,9 +284,7 @@ def populate_dev( bind_mounts["fuse"] = exitstack.enter_context( open_tree(origdev / "fuse", OpenTreeFlags.CLONE) ) - if pidns: - symlinks["ptmx"] = "pts/ptmx" - else: + if pts == "host": bind_mounts["pts"] = exitstack.enter_context( open_tree( origdev / "pts", @@ -291,6 +295,8 @@ def populate_dev( bind_mounts["ptmx"] = exitstack.enter_context( open_tree(origdev / "ptmx", OpenTreeFlags.CLONE) ) + elif pts != "absent": + symlinks["ptmx"] = "pts/ptmx" if tun: directories.add("net") files.add("net/tun") @@ -320,7 +326,7 @@ def populate_dev( (newdev / fn).mknod(stat.S_IFREG) for fn, target in symlinks.items(): (newdev / fn).symlink_to(target) - if pidns: + if pts == "new": mount( "devpts", newdev / "pts", diff --git a/tests/test_simple.py b/tests/test_simple.py index 38a253d..114b922 100644 --- a/tests/test_simple.py +++ b/tests/test_simple.py @@ -239,7 +239,7 @@ class UnshareTest(unittest.TestCase): ) linuxnamespaces.mount("tmpfs", "/mnt", "tmpfs", data="mode=0755") os.mkdir("/mnt/dev") - linuxnamespaces.populate_dev("/", "/mnt", pidns=False) + linuxnamespaces.populate_dev("/", "/mnt", pts="host") self.assertTrue(os.access("/mnt/dev/null", os.W_OK)) pathlib.Path("/mnt/dev/null").write_text("") |