summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelmut Grohne <helmut@subdivi.de>2024-03-03 20:51:35 +0100
committerHelmut Grohne <helmut@subdivi.de>2024-03-03 20:54:22 +0100
commitd401e94ca5f7945d3da2c2927bfb038da3a066dd (patch)
tree09c878878e5a738de03e20eb63547124cb73a910
parent64a660360e1cc20c5c5c14fcb4cdaa9b12c562f6 (diff)
downloadpython-linuxnamespaces-d401e94ca5f7945d3da2c2927bfb038da3a066dd.tar.gz
add function for prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, ...)
-rwxr-xr-xexamples/withallsubuids.py10
-rw-r--r--linuxnamespaces/syscalls.py30
2 files changed, 29 insertions, 11 deletions
diff --git a/examples/withallsubuids.py b/examples/withallsubuids.py
index ead0482..3bed3bc 100755
--- a/examples/withallsubuids.py
+++ b/examples/withallsubuids.py
@@ -43,15 +43,7 @@ def main() -> None:
capabilities.inheritable = capabilities.permitted & capabilities.effective
capabilities.set()
# Add all inheritable capabilities to the ambient set.
- caps = capabilities.inheritable
- while caps:
- cap = caps & (~caps + 1)
- caps ^= cap
- linuxnamespaces.prctl(
- 47, # PR_CAP_AMBIENT
- 2, # PR_CAP_AMBIENT_RAISE
- cap.bit_length() - 1,
- )
+ linuxnamespaces.prctl_raise_ambient_capabilities(capabilities.inheritable)
if len(sys.argv) > 1:
os.execvp(sys.argv[1], sys.argv[1:])
else:
diff --git a/linuxnamespaces/syscalls.py b/linuxnamespaces/syscalls.py
index c22a9d8..8f5e25b 100644
--- a/linuxnamespaces/syscalls.py
+++ b/linuxnamespaces/syscalls.py
@@ -337,6 +337,12 @@ class OpenTreeFlags(enum.IntFlag):
)
+class PrctlOption(enum.IntEnum):
+ """This value may be supplied to prctl(2) as option."""
+
+ PR_CAP_AMBIENT = 47
+
+
class UmountFlags(enum.IntFlag):
"""This value may be supplied to umount2(2) as flags."""
@@ -622,11 +628,31 @@ def pivot_root(new_root: PathConvertible, put_old: PathConvertible) -> None:
"""Python wrapper for pivot_root(2)."""
call_libc("pivot_root", os.fsencode(new_root), os.fsencode(put_old))
+
def prctl(
- option: int, arg2: int = 0, arg3: int = 0, arg4: int = 0, arg5: int = 0
+ option: PrctlOption | int,
+ arg2: int = 0,
+ arg3: int = 0,
+ arg4: int = 0,
+ arg5: int = 0,
) -> int:
"""Python wrapper for prctl(2)."""
- return call_libc("prctl", option, arg2, arg3, arg4, arg5)
+ return call_libc("prctl", int(option), arg2, arg3, arg4, arg5)
+
+
+def prctl_raise_ambient_capabilities(capabilities: int) -> None:
+ """Raise all ambient capabilities in the given bitfield. If multiple bits
+ are set, this results in multiple prctl(2) syscalls.
+ """
+ while capabilities:
+ cap = capabilities & (~capabilities + 1)
+ capabilities ^= cap
+ prctl(
+ PrctlOption.PR_CAP_AMBIENT,
+ 2, # PR_CAP_AMBIENT_RAISE
+ cap.bit_length() - 1,
+ )
+
def setns(fd: int, nstype: CloneFlags = CloneFlags.NONE) -> None:
"""Python wrapper for setns(2)."""