From 9e74e6213b1a7c4dc836746d32ab5762613fb05a Mon Sep 17 00:00:00 2001 From: Akira Moroo Date: Sun, 12 Jan 2025 08:49:03 +0000 Subject: [PATCH 1/2] [WIP] main: Support Android namespaces Signed-off-by: Akira Moroo --- main.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index a84a011..e5a4baf 100644 --- a/main.c +++ b/main.c @@ -16,6 +16,10 @@ #include #include +#ifdef __ANDROID__ +#include +#endif /* __ANDROID__ */ + #ifdef SUPPLEMENTAL__SYSCALL_RECORD /* * SUPPLEMENTAL: syscall record without syscalls @@ -681,6 +685,72 @@ static void setup_trampoline(void) { } } +#ifdef __ANDROID__ +// REF: https://gist.github.com/khanhduytran0/faee2be9c8fd1282783b936156a03e1c +static void *_libdl_handle = NULL; +static struct android_namespace_t *(*_create_namespace)( + const char *, const char *, const char *, uint64_t, const char *, + struct android_namespace_t *) = NULL; +static void *(*_dlopen_ext)(const char *, int, + const android_dlextinfo *) = NULL; + +static void *get_libdl_handle(void) { + return _libdl_handle ? _libdl_handle : dlopen("libdl.so", RTLD_NOW); +} + +static void *create_namespace(const char *name, const char *ld_library_path, + const char *default_library_path, uint64_t type, + const char *permitted_when_isolated_path, + struct android_namespace_t *parent_namespace) { + if (!_create_namespace) { + void *handle = get_libdl_handle(); + if (!handle) { + goto fallback; + } + + _create_namespace = (struct android_namespace_t * + (*)(const char *, const char *, const char *, uint64_t, + const char *, struct android_namespace_t *)) + dlsym(handle, "android_create_namespace"); + if (!_create_namespace) { + goto fallback; + } + } + + return _create_namespace(name, ld_library_path, default_library_path, type, + permitted_when_isolated_path, parent_namespace); + +fallback: + return NULL; +} + +static void *dlopen_ext(const char *filename, int flags, + const android_dlextinfo *extinfo) { + if (!_dlopen_ext) { + void *handle = get_libdl_handle(); + if (!handle) { + goto fallback; + } + + _dlopen_ext = + (void *(*)(const char *, int, const android_dlextinfo *))dlsym( + handle, "android_dlopen_ext"); + if (!_dlopen_ext) { + goto fallback; + } + } + + if (extinfo == NULL) { + goto fallback; + } + + return _dlopen_ext(filename, flags, extinfo); + +fallback: + return dlopen(filename, flags); +} +#endif /* __ANDROID__ */ + static void load_hook_lib(void) { void *handle; { @@ -692,11 +762,22 @@ static void load_hook_lib(void) { return; } -#ifdef __GLIBC__ +#if defined(__GLIBC__) handle = dlmopen(LM_ID_NEWLM, filename, RTLD_NOW | RTLD_LOCAL); -#else +#elif defined(__ANDROID__) + struct android_namespace_t *ns = create_namespace( + "hook-namespace", NULL, + "/system/lib:/vendor/lib:/system/vendor/lib/hw/:/vendor/lib/hw", + 0 /* ANDROID_NAMESPACE_TYPE_REGULAR */, NULL, NULL); + + android_dlextinfo extinfo = { + .flags = ANDROID_DLEXT_USE_NAMESPACE, + .library_namespace = ns, + }; + handle = dlopen_ext(filename, RTLD_NOW | RTLD_LOCAL, &extinfo); +#else /* !__GLIBC__ && !__ANDROID__ */ handle = dlopen(filename, RTLD_NOW | RTLD_LOCAL); -#endif +#endif /* __GLIBC__ || __ANDROID__ */ if (!handle) { fprintf(stderr, "dlopen/dlmopen failed: %s\n\n", dlerror()); fprintf( From 0797115a717c326c731baadc5220eeb00c231613 Mon Sep 17 00:00:00 2001 From: Akira Moroo Date: Mon, 13 Jan 2025 02:27:16 +0000 Subject: [PATCH 2/2] [WIP] main: Use android_get_exported_namespace Signed-off-by: Akira Moroo --- main.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/main.c b/main.c index e5a4baf..e5a9fdd 100644 --- a/main.c +++ b/main.c @@ -688,9 +688,9 @@ static void setup_trampoline(void) { #ifdef __ANDROID__ // REF: https://gist.github.com/khanhduytran0/faee2be9c8fd1282783b936156a03e1c static void *_libdl_handle = NULL; -static struct android_namespace_t *(*_create_namespace)( - const char *, const char *, const char *, uint64_t, const char *, - struct android_namespace_t *) = NULL; +static void *_libc_handle = NULL; +static struct android_namespace_t *(*_get_exported_namespace)(const char *) = + NULL; static void *(*_dlopen_ext)(const char *, int, const android_dlextinfo *) = NULL; @@ -698,27 +698,28 @@ static void *get_libdl_handle(void) { return _libdl_handle ? _libdl_handle : dlopen("libdl.so", RTLD_NOW); } -static void *create_namespace(const char *name, const char *ld_library_path, - const char *default_library_path, uint64_t type, - const char *permitted_when_isolated_path, - struct android_namespace_t *parent_namespace) { - if (!_create_namespace) { - void *handle = get_libdl_handle(); +static void *get_libc_handle(void) { + return _libc_handle ? _libc_handle + : dlopen("/system/lib64/libc.so", RTLD_NOW); +} + +static struct android_namespace_t *get_exported_namespace(const char *name) { + if (!_get_exported_namespace) { + void *handle = get_libc_handle(); if (!handle) { + fprintf(stderr, "dlopen failed: %s\n", dlerror()); goto fallback; } - _create_namespace = (struct android_namespace_t * - (*)(const char *, const char *, const char *, uint64_t, - const char *, struct android_namespace_t *)) - dlsym(handle, "android_create_namespace"); - if (!_create_namespace) { + _get_exported_namespace = (struct android_namespace_t * (*)(const char *)) + dlsym(handle, "__loader_android_get_exported_namespace"); + if (!_get_exported_namespace) { + fprintf(stderr, "dlsym failed: %s\n", dlerror()); goto fallback; } } - return _create_namespace(name, ld_library_path, default_library_path, type, - permitted_when_isolated_path, parent_namespace); + return _get_exported_namespace(name); fallback: return NULL; @@ -765,11 +766,7 @@ static void load_hook_lib(void) { #if defined(__GLIBC__) handle = dlmopen(LM_ID_NEWLM, filename, RTLD_NOW | RTLD_LOCAL); #elif defined(__ANDROID__) - struct android_namespace_t *ns = create_namespace( - "hook-namespace", NULL, - "/system/lib:/vendor/lib:/system/vendor/lib/hw/:/vendor/lib/hw", - 0 /* ANDROID_NAMESPACE_TYPE_REGULAR */, NULL, NULL); - + struct android_namespace_t *ns = get_exported_namespace("default"); android_dlextinfo extinfo = { .flags = ANDROID_DLEXT_USE_NAMESPACE, .library_namespace = ns,