diff --git a/tools/nativeguest/hook/exec.c b/tools/nativeguest/hook/exec.c index d973ac134..0728620a1 100644 --- a/tools/nativeguest/hook/exec.c +++ b/tools/nativeguest/hook/exec.c @@ -245,7 +245,7 @@ static int ddnatv_execve(const char *filename, char *const argv[], char *const e char resolved_target[PATH_MAX]; // Only intercept binaries/scripts within DDNATV_ROOT - if (g_ddnatv_root[0] != '\0' && strncmp(target, g_ddnatv_root, g_ddnatv_root_len) == 0) { + if ((g_ddnatv_root[0] != '\0' && strncmp(target, g_ddnatv_root, g_ddnatv_root_len) == 0) || is_mapped_guest_path(filename)) { struct exec_probe probe; const char *elf_target = select_exec_target(target, resolved_target, sizeof(resolved_target), &probe); if (probe.is_elf && !probe.is_dynamic) static_elf = elf_target; @@ -798,7 +798,7 @@ static int ddnatv_posix_spawn(pid_t *pid, const char *path, } char *const *orig_ep = envp ? envp : environ; - int in_root = g_ddnatv_root[0] != '\0' && strncmp(target, g_ddnatv_root, g_ddnatv_root_len) == 0; + int in_root = (g_ddnatv_root[0] != '\0' && strncmp(target, g_ddnatv_root, g_ddnatv_root_len) == 0) || is_mapped_guest_path(path); struct exec_probe probe; char resolved_target[PATH_MAX]; diff --git a/tools/nativeguest/hook/paths.c b/tools/nativeguest/hook/paths.c index cb8c66f2e..cefabd51d 100644 --- a/tools/nativeguest/hook/paths.c +++ b/tools/nativeguest/hook/paths.c @@ -100,6 +100,18 @@ static inline const char *get_rootfs_subpath(const char *target) { return NULL; } +// A guest path that a session mount puts outside the rootfs (/run/droiddeck, a game library): a +// program or script there is the guest's, and a script's "#!/bin/sh" is the rootfs shell. The +// kernel ran them with Android's /system/bin/sh, which found no /usr/bin/kwin_wayland. +static int is_mapped_guest_path(const char *path) { + if (!path || path[0] != '/') return 0; + for (int i = 0; i < g_nbinds; i++) { + const struct ddnatv_bind *b = &g_binds[i]; + if (!b->identity && is_path_prefix(path, b->dst, b->dst_len)) return 1; + } + return 0; +} + // Android's own mounts and files, which must never be redirected into the rootfs. // `path` starts with '/'; a prefix can only match when its second character does. static int is_android_host_path(const char *path) {