From 5e004a85dd660d41ae7c3519679d2cfae8919e77 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Thu, 18 Jan 2024 22:25:18 +0100 Subject: add withallsubuids.py example --- examples/withallsubuids.py | 65 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100755 examples/withallsubuids.py diff --git a/examples/withallsubuids.py b/examples/withallsubuids.py new file mode 100755 index 0000000..8b90e9a --- /dev/null +++ b/examples/withallsubuids.py @@ -0,0 +1,65 @@ +#!/usr/bin/python3 +# Copyright 2024 Helmut Grohne +# SPDX-License-Identifier: GPL-3 + +"""Map all available ranges from /etc/subuid and /etc/subgid as identity and +run a given command with all capabilities (including CAP_DAC_OVERRIDE) +inherited. +""" + +import os +import sys + +if __file__.split("/")[-2:-1] == ["examples"]: + sys.path.insert(0, "/".join(__file__.split("/")[:-2])) + +import linuxnamespaces + + +def main() -> None: + # Construct an identity mapping of all available user/group ids + uidmap = [ + linuxnamespaces.IDMapping(os.getuid(), os.getuid(), 1), + *( + linuxnamespaces.IDMapping(start, start, count) + for start, count + in linuxnamespaces.IDAllocation.loadsubid("uid").ranges + ), + ] + gidmap = [ + linuxnamespaces.IDMapping(os.getgid(), os.getgid(), 1), + *( + linuxnamespaces.IDMapping(start, start, count) + for start, count + in linuxnamespaces.IDAllocation.loadsubid("gid").ranges + ), + ] + linuxnamespaces.unshare_user_idmap(uidmap, gidmap) + + # We haven't changed uid. We still are non-root, but the user namespace + # augmented our permitted and effective capabilities! Add them to the + # inheritable set. + capabilities = linuxnamespaces.CapabilitySets.get() + 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.call_libc( + "prctl", + 47, # PR_CAP_AMBIENT + 2, # PR_CAP_AMBIENT_RAISE + cap.bit_length() - 1, + 0, + 0, + ) + if len(sys.argv) > 1: + os.execvp(sys.argv[1], sys.argv[1:]) + else: + os.execvp(os.environ["SHELL"], [os.environ["SHELL"]]) + + +if __name__ == "__main__": + main() -- cgit v1.2.3