diff options
Diffstat (limited to 'linuxnamespaces')
-rw-r--r-- | linuxnamespaces/__init__.py | 39 |
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, |