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
# SPDX-License-Identifier: GPL-3.0-or-later
from pmb.core.arch import Arch
from pmb.helpers import logging
import socket
from contextlib import closing
import pmb.chroot
import pmb.helpers.mount
from pmb.core import Chroot, ChrootType
from pmb.core import Chroot
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:
"""
: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:
# Stop daemons
kill_adb()
kill_sccache()
# Umount installation-related paths (order is important!)
# pmb.helpers.mount.umount_all(chroot / "mnt/install")
shutdown_cryptsetup_device("pm_crypt")

View file

@ -27,6 +27,7 @@ BTRFS_SUPER_MAGIC = 0x9123683E
CAP_NET_ADMIN = 12
CAP_SYS_ADMIN = 21
CLONE_NEWIPC = 0x08000000
CLONE_NEWPID = 0x20000000
CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x00020000
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()
sandbox.acquire_privileges(become_root=False)
# Unshare mount namespace
sandbox.unshare(sandbox.CLONE_NEWNS)
# sandbox.seccomp_suppress(chown=True)
# Unshare mount and PID namespaces. We create a new PID namespace so
# that any log-running daemons (e.g. adbd, sccache) will be killed when
# 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: ")
# with open("/proc/self/status", "rb") as f: