From c49dfd272d994b1cdaa14107fee66be84b80c06b Mon Sep 17 00:00:00 2001 From: Alessandro Astone Date: Sun, 22 Jan 2023 00:13:08 +0100 Subject: [PATCH] lxc: Create session-specific mount entries Closes: #704 --- data/configs/config_base | 1 + tools/actions/container_manager.py | 19 ++++--- tools/helpers/lxc.py | 82 ++++++++++++++++++++---------- 3 files changed, 68 insertions(+), 34 deletions(-) diff --git a/data/configs/config_base b/data/configs/config_base index 27e070f..99fd198 100644 --- a/data/configs/config_base +++ b/data/configs/config_base @@ -12,6 +12,7 @@ lxc.mount.auto = cgroup:ro sys:ro proc lxc.console.path = none lxc.include = /var/lib/waydroid/lxc/waydroid/config_nodes +lxc.include = /var/lib/waydroid/lxc/waydroid/config_session lxc.hook.post-stop = /dev/null diff --git a/tools/actions/container_manager.py b/tools/actions/container_manager.py index 0092f1e..e537e18 100644 --- a/tools/actions/container_manager.py +++ b/tools/actions/container_manager.py @@ -145,10 +145,6 @@ def do_start(args, session): helpers.protocol.set_aidl_version(args) - # Mount data - helpers.mount.bind(args, session["waydroid_data"], - tools.config.defaults["data"]) - # Cgroup hacks if which("start"): command = ["start", "cgroup-lite"] @@ -165,6 +161,14 @@ def do_start(args, session): # Set permissions set_permissions(args) + # Create session-specific LXC config file + helpers.lxc.generate_session_lxc_config(args, session) + # Backwards compatibility + with open(tools.config.defaults["lxc"] + "/waydroid/config") as f: + if "config_session" not in f.read(): + helpers.mount.bind(args, session["waydroid_data"], + tools.config.defaults["data"]) + helpers.lxc.start(args) services.hardware_manager.start(args) @@ -200,8 +204,11 @@ def stop(args, quit_session=True): # Umount rootfs helpers.images.umount_rootfs(args) - # Umount data - helpers.mount.umount_all(args, tools.config.defaults["data"]) + # Backwards compatibility + try: + helpers.mount.umount_all(args, tools.config.defaults["data"]) + except: + pass if "session" in args: if quit_session: diff --git a/tools/helpers/lxc.py b/tools/helpers/lxc.py index c0ac9d1..0221d0b 100644 --- a/tools/helpers/lxc.py +++ b/tools/helpers/lxc.py @@ -21,22 +21,24 @@ def get_lxc_version(args): else: return 0 +def add_node_entry(nodes, src, dist, mnt_type, options, check): + if check and not os.path.exists(src): + return False + entry = "lxc.mount.entry = " + entry += src + " " + if dist is None: + dist = src[1:] + entry += dist + " " + entry += mnt_type + " " + entry += options + nodes.append(entry) + return True def generate_nodes_lxc_config(args): + nodes = [] def make_entry(src, dist=None, mnt_type="none", options="bind,create=file,optional 0 0", check=True): - if check and not os.path.exists(src): - return False - entry = "lxc.mount.entry = " - entry += src + " " - if dist is None: - dist = src[1:] - entry += dist + " " - entry += mnt_type + " " - entry += options - nodes.append(entry) - return True + return add_node_entry(nodes, src, dist, mnt_type, options, check) - nodes = [] # Necessary dev nodes make_entry("tmpfs", "dev", "tmpfs", "nosuid 0 0", False) make_entry("/dev/zero") @@ -84,19 +86,10 @@ def generate_nodes_lxc_config(args): # Low memory killer sys node make_entry("/sys/module/lowmemorykiller", options="bind,create=dir,optional 0 0") - # Mount /data - make_entry("tmpfs", "mnt", "tmpfs", "mode=0755,uid=0,gid=1000", False) - make_entry(tools.config.defaults["data"], "data", options="bind 0 0", check=False) - # Mount host permissions make_entry(tools.config.defaults["host_perms"], "vendor/etc/host-permissions", options="bind,optional 0 0") - # Recursive mount /run to provide necessary host sockets - make_entry("/run", options="rbind,create=dir 0 0") - # And /dev/shm - make_entry("/dev/shm", options="rbind,create=dir,optional 0 0") - # Necessary sw_sync node for HWC make_entry("/dev/sw_sync") make_entry("/sys/kernel/debug", options="rbind,create=dir,optional 0 0") @@ -118,14 +111,10 @@ def generate_nodes_lxc_config(args): make_entry("/mnt/wslg", "mnt_extra/wslg", options="rbind,create=dir,optional 0 0") - # var - make_entry("tmpfs", "var", "tmpfs", "nodev 0 0", False) - make_entry("/var/run", options="rbind,create=dir,optional 0 0") - - # tmp + # Make a tmpfs at every possible rootfs mountpoint make_entry("tmpfs", "tmp", "tmpfs", "nodev 0 0", False) - for n in glob.glob("/tmp/run-*"): - make_entry(n, options="rbind,create=dir,optional 0 0") + make_entry("tmpfs", "var", "tmpfs", "nodev 0 0", False) + make_entry("tmpfs", "run", "tmpfs", "nodev 0 0", False) # NFC config make_entry("/system/etc/libnfc-nci.conf", options="bind,optional 0 0") @@ -185,6 +174,43 @@ def set_lxc_config(args): command = ["mv", config_nodes_tmp_path, lxc_path] tools.helpers.run.user(args, command) + # Create empty file + open(os.path.join(lxc_path, "config_session"), mode="w").close() + +def generate_session_lxc_config(args, session): + nodes = [] + def make_entry(src, dist=None, mnt_type="none", options="rbind,create=file 0 0"): + if any(x in src for x in ["\n", "\r"]): + logging.warning("User-provided mount path contains illegal character") + return False + if dist is None and (not os.path.exists(src) or + str(os.stat(src).st_uid) != session["user_id"]): + logging.warning("User-provided mount path is not owned by user") + return False + return add_node_entry(nodes, src, dist, mnt_type, options, check=False) + + # Make sure XDG_RUNTIME_DIR exists + if not make_entry("tmpfs", session["xdg_runtime_dir"], options="create=dir 0 0"): + raise OSError("Failed to create XDG_RUNTIME_DIR mount point") + + wayland_socket = os.path.realpath(os.path.join(session["xdg_runtime_dir"], session["wayland_display"])) + if not make_entry(wayland_socket): + raise OSError("Failed to bind Wayland socket") + + pulse_socket = os.path.join(session["pulse_runtime_path"], "native") + make_entry(pulse_socket) + + if not make_entry(session["waydroid_data"], "data", options="rbind 0 0"): + raise OSError("Failed to bind userdata") + + lxc_path = tools.config.defaults["lxc"] + "/waydroid" + config_nodes_tmp_path = args.work + "/config_session" + config_nodes = open(config_nodes_tmp_path, "w") + for node in nodes: + config_nodes.write(node + "\n") + config_nodes.close() + command = ["mv", config_nodes_tmp_path, lxc_path] + tools.helpers.run.user(args, command) def make_base_props(args): def find_hal(hardware): -- 2.47.3