summaryrefslogtreecommitdiff
path: root/linuxnamespaces
diff options
context:
space:
mode:
Diffstat (limited to 'linuxnamespaces')
-rw-r--r--linuxnamespaces/__init__.py39
1 files changed, 39 insertions, 0 deletions
diff --git a/linuxnamespaces/__init__.py b/linuxnamespaces/__init__.py
index 2b92462..e305b4e 100644
--- a/linuxnamespaces/__init__.py
+++ b/linuxnamespaces/__init__.py
@@ -426,6 +426,45 @@ def populate_dev(
move_mount(fd, newdev / fn)
+def populate_proc(
+ origroot: AtLocationLike,
+ newroot: PathConvertible,
+ namespaces: CloneFlags,
+) -> None:
+ """Mount a /proc hierarchy.
+
+ Note that a user with CAP_SYS_ADMIN can change read-only bind mounts.
+ Still those bind mounts provide guidance to the container as to which
+ aspects it should manage.
+ """
+ assert namespaces & CloneFlags.NEWNS == CloneFlags.NEWNS
+ newproc = AtLocation(newroot) / "proc"
+ rwns = CloneFlags.NEWPID
+ if namespaces & rwns == rwns:
+ mount(
+ "proc",
+ newproc,
+ "proc",
+ MountFlags.NOSUID | MountFlags.NODEV | MountFlags.NOEXEC,
+ )
+ else:
+ bind_mount(AtLocation(origroot) / "proc", newproc, True)
+ with _ExceptionExitCallback(umount, newproc, UmountFlags.DETACH):
+ rwns |= CloneFlags.NEWUSER | CloneFlags.NEWIPC | CloneFlags.NEWUTS
+ if namespaces & rwns != rwns:
+ psn: AtLocation | None = None
+ if namespaces & CloneFlags.NEWNET == CloneFlags.NEWNET:
+ psn = open_tree(
+ newproc / "sys/net",
+ OpenTreeFlags.OPEN_TREE_CLONE | OpenTreeFlags.AT_RECURSIVE,
+ )
+ bind_mount(newproc / "sys", newproc / "sys", True, True)
+ if psn is not None:
+ move_mount(psn, newproc / "sys/net")
+ elif namespaces & CloneFlags.NEWNET != CloneFlags.NEWNET:
+ bind_mount(newproc / "sys/net", newproc / "sys/net", True, True)
+
+
def populate_sys(
origroot: AtLocationLike,
newroot: PathConvertible,