From a826655ffcdeb6563899d0143e21689ea386c8b0 Mon Sep 17 00:00:00 2001 From: igo95862 Date: Thu, 15 Oct 2020 18:14:56 +0300 Subject: [PATCH] bubblejail_helper can now reap its own children Helper will now be PID 1 inside the name space. This means no process can escape us. Fixes Code. --- bubblejail/bubblejail_helper.py | 35 ++++++++++++++++++++++++++----- bubblejail/bubblejail_instance.py | 2 ++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/bubblejail/bubblejail_helper.py b/bubblejail/bubblejail_helper.py index e95459e..2c6d7e0 100644 --- a/bubblejail/bubblejail_helper.py +++ b/bubblejail/bubblejail_helper.py @@ -17,15 +17,16 @@ from argparse import REMAINDER as ARG_REMAINDER from argparse import ArgumentParser from asyncio import (AbstractServer, CancelledError, Event, StreamReader, - StreamWriter, Task, create_subprocess_exec, create_task) -from asyncio import run as async_run -from asyncio import sleep, start_unix_server + StreamWriter, Task, create_subprocess_exec, create_task, + get_event_loop, sleep, start_unix_server) from asyncio.subprocess import DEVNULL, PIPE, STDOUT from json import dumps as json_dumps from json import loads as json_loads +from os import WNOHANG, waitpid from pathlib import Path +from signal import SIGCHLD from typing import (Any, Awaitable, Dict, Generator, List, Literal, Optional, - Union) + Tuple, Union) from xdg.BaseDirectory import get_runtime_dir @@ -138,6 +139,28 @@ def request_selector(data: bytes) -> RpcRequests: # endregion Rpc +def handle_children() -> None: + """Reaps dead children.""" + # Needs to be in exception + # Seems like the sometimes python raises ChildProcessError + # Most often however (0, 0) + wait_pid_tuple: Tuple[int, int] = (0, 0) + try: + # Walrus in action + while (wait_pid_tuple := waitpid(-1, WNOHANG)) != (0, 0): + exit_pid, exit_code = wait_pid_tuple + if exit_pid == 0: + return + + if __debug__: + print('Reaped: ', exit_pid, + ' Exit code: ', exit_code, + flush=True) + + except ChildProcessError: + ... + + class BubblejailHelper(Awaitable[bool]): def __init__( self, @@ -375,7 +398,9 @@ async def run_helper() -> None: await helper.start_async() await helper - async_run(run_helper()) + event_loop = get_event_loop() + event_loop.add_signal_handler(SIGCHLD, handle_children) + event_loop.run_until_complete(run_helper()) if __name__ == '__main__': diff --git a/bubblejail/bubblejail_instance.py b/bubblejail/bubblejail_instance.py index 6b83ff3..b2acac3 100644 --- a/bubblejail/bubblejail_instance.py +++ b/bubblejail/bubblejail_instance.py @@ -398,6 +398,8 @@ def genetate_args(self) -> None: self.bwrap_options_args.append('--unshare-all') # Die with parent self.bwrap_options_args.append('--die-with-parent') + # We have our own reaper + self.bwrap_options_args.append('--as-pid-1') if not self.is_shell_debug: # Set new session