1
0
Fork 1
mirror of https://gitlab.postmarketos.org/postmarketOS/pmbootstrap.git synced 2025-07-25 21:45:11 +03:00

pmbootstrap: unshare PID namespaec

Put ourselves in a new PID namespace so that daemons we might start in
the chroot like adbd will be killed on exit.

This simplifies "shutdown" since we no longer need to kill these
processes.

Signed-off-by: Casey Connolly <kcxt@postmarketos.org>
This commit is contained in:
Casey Connolly 2025-05-26 16:19:24 +02:00
parent e8a9ce615f
commit 9dc294dbbf
3 changed files with 20 additions and 32 deletions

View file

@ -1,37 +1,13 @@
# Copyright 2023 Oliver Smith # Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from pmb.core.arch import Arch
from pmb.helpers import logging from pmb.helpers import logging
import socket
from contextlib import closing
import pmb.chroot import pmb.chroot
import pmb.helpers.mount import pmb.helpers.mount
from pmb.core import Chroot, ChrootType from pmb.core import Chroot
from pmb.core.context import get_context from pmb.core.context import get_context
def kill_adb() -> None:
"""
Kill adb daemon if it's running.
"""
port = 5038
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
if sock.connect_ex(("127.0.0.1", port)) == 0:
pmb.chroot.root(["adb", "-P", str(port), "kill-server"])
def kill_sccache() -> None:
"""
Kill sccache daemon if it's running. Unlike ccache it automatically spawns
a daemon when you call it and exits after some time of inactivity.
"""
port = 4226
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
if sock.connect_ex(("127.0.0.1", port)) == 0:
pmb.chroot.root(["sccache", "--stop-server"])
def shutdown_cryptsetup_device(name: str) -> None: def shutdown_cryptsetup_device(name: str) -> None:
""" """
:param name: cryptsetup device name, usually "pm_crypt" in pmbootstrap :param name: cryptsetup device name, usually "pm_crypt" in pmbootstrap
@ -59,10 +35,6 @@ def shutdown_cryptsetup_device(name: str) -> None:
def shutdown(only_install_related: bool = False) -> None: def shutdown(only_install_related: bool = False) -> None:
# Stop daemons
kill_adb()
kill_sccache()
# Umount installation-related paths (order is important!) # Umount installation-related paths (order is important!)
# pmb.helpers.mount.umount_all(chroot / "mnt/install") # pmb.helpers.mount.umount_all(chroot / "mnt/install")
shutdown_cryptsetup_device("pm_crypt") shutdown_cryptsetup_device("pm_crypt")

View file

@ -27,6 +27,7 @@ BTRFS_SUPER_MAGIC = 0x9123683E
CAP_NET_ADMIN = 12 CAP_NET_ADMIN = 12
CAP_SYS_ADMIN = 21 CAP_SYS_ADMIN = 21
CLONE_NEWIPC = 0x08000000 CLONE_NEWIPC = 0x08000000
CLONE_NEWPID = 0x20000000
CLONE_NEWNET = 0x40000000 CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x00020000 CLONE_NEWNS = 0x00020000
CLONE_NEWUSER = 0x10000000 CLONE_NEWUSER = 0x10000000

View file

@ -14,9 +14,24 @@ os.environ["SHELL"] = "/bin/sh" if os.path.exists("/bin/sh") else "/bin/bash"
original_uid = os.geteuid() original_uid = os.geteuid()
sandbox.acquire_privileges(become_root=False) sandbox.acquire_privileges(become_root=False)
# Unshare mount namespace # Unshare mount and PID namespaces. We create a new PID namespace so
sandbox.unshare(sandbox.CLONE_NEWNS) # that any log-running daemons (e.g. adbd, sccache) will be killed when
# sandbox.seccomp_suppress(chown=True) # pmbootstrap exits
sandbox.unshare(sandbox.CLONE_NEWNS | sandbox.CLONE_NEWPID)
# We are now PID 1 in a new PID namespace. We don't want to run all our
# logic as PID 1 since subprocess.Popen() seemingly causes our PID to
# change. So we fork now, the child process continues and we just wait
# around and propagate the exit code.
# This is all kinda hacky, we should integrate this with the acquire_privileges()
# implementation since it's already doing similar fork shenanigans, we could
# save a call to fork() this way. But for now it's fine.
pid = os.fork()
if pid > 0:
# We are PID 1! let's hang out
pid, wstatus = os.waitpid(pid, 0)
exitcode = os.waitstatus_to_exitcode(wstatus)
os._exit(exitcode)
# print("Caps: ") # print("Caps: ")
# with open("/proc/self/status", "rb") as f: # with open("/proc/self/status", "rb") as f: