summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xexamples/chrootfuse.py2
-rwxr-xr-xexamples/chroottar.py2
-rwxr-xr-xexamples/userchroot.py2
-rw-r--r--linuxnamespaces/__init__.py16
-rw-r--r--tests/test_simple.py2
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("")