From 91b41f523450dba68d958fd715e670c0a8e77b0c Mon Sep 17 00:00:00 2001 From: Luca Bacci Date: Mon, 25 Sep 2023 19:15:04 +0200 Subject: [PATCH 1/2] tests/gutils-user-database: do not hardcode library name Use build_tgt.full_path() and import('fs').name() --- glib/tests/meson.build | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/glib/tests/meson.build b/glib/tests/meson.build index e84e986d8..8525b10d7 100644 --- a/glib/tests/meson.build +++ b/glib/tests/meson.build @@ -226,23 +226,22 @@ else 'unix' : {}, } if have_rtld_next and glib_build_shared + getpwuid_preload = shared_library('getpwuid-preload', + 'getpwuid-preload.c', + name_prefix : '', + dependencies: libdl_dep, + install_dir : installed_tests_execdir, + install_tag : 'tests', + install: installed_tests_enabled) + glib_tests += { 'gutils-user-database' : { - 'depends' : [ - shared_library('getpwuid-preload', - 'getpwuid-preload.c', - name_prefix : '', - dependencies: libdl_dep, - install_dir : installed_tests_execdir, - install_tag : 'tests', - install: installed_tests_enabled, - ), - ], + 'depends' : [], 'env' : { - 'LD_PRELOAD': '@0@/getpwuid-preload.so'.format(meson.current_build_dir()), + 'LD_PRELOAD': getpwuid_preload.full_path() }, 'installed_tests_env' : { - 'LD_PRELOAD': '@0@/getpwuid-preload.so'.format(installed_tests_execdir), + 'LD_PRELOAD': installed_tests_execdir / fs.name(getpwuid_preload.full_path()) }, }, } From 991cb9ef8ccfae06d33be8884d0b23a84d061d21 Mon Sep 17 00:00:00 2001 From: Luca Bacci Date: Tue, 26 Sep 2023 12:09:02 +0200 Subject: [PATCH 2/2] tests/gutils-user-database: Fix test on macOS Use DYLD interposing on macOS --- glib/tests/getpwuid-preload.c | 76 ++++++++++++++++++++--------------- glib/tests/meson.build | 10 ++++- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/glib/tests/getpwuid-preload.c b/glib/tests/getpwuid-preload.c index edf0028a8..0c005a8b4 100644 --- a/glib/tests/getpwuid-preload.c +++ b/glib/tests/getpwuid-preload.c @@ -25,57 +25,67 @@ #include #include -#undef getpwuid +#ifndef __APPLE__ -static struct passwd my_pw; +#define GET_REAL(func) \ + (real_##func = dlsym (RTLD_NEXT, #func)) + +#define DEFINE_WRAPPER(return_type, func, argument_list) \ + static return_type (* real_##func) argument_list; \ + return_type func argument_list + +#else + +#define GET_REAL(func) \ + func + +/* https://opensource.apple.com/source/dyld/dyld-852.2/include/mach-o/dyld-interposing.h */ +#define DYLD_INTERPOSE(_replacement,_replacee) \ + __attribute__((used)) static struct{ const void* replacement; const void* replacee; } _interpose_##_replacee \ + __attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacement, (const void*)(unsigned long)&_replacee }; + +#define DEFINE_WRAPPER(return_type, func, argument_list) \ + static return_type wrap_##func argument_list; \ + DYLD_INTERPOSE(wrap_##func, func) \ + static return_type wrap_##func argument_list + +#endif /* __APPLE__ */ /* This is used in gutils.c used to make sure utility functions * handling user information do not crash on bad data (for example * caused by getpwuid returning some NULL elements. */ -struct passwd * -getpwuid (uid_t uid) + +#undef getpwuid + +static struct passwd my_pw; + +DEFINE_WRAPPER (struct passwd *, getpwuid, (uid_t uid)) { - static struct passwd *(*real_getpwuid) (uid_t); - struct passwd *pw; - - if (real_getpwuid == NULL) - real_getpwuid = dlsym (RTLD_NEXT, "getpwuid"); - - pw = real_getpwuid (uid); + struct passwd *pw = GET_REAL (getpwuid) (uid); my_pw = *pw; my_pw.pw_name = NULL; return &my_pw; } -int -getpwnam_r (const char *name, struct passwd *pwd, char buf[], size_t buflen, struct passwd **result) +DEFINE_WRAPPER (int, getpwnam_r, (const char *name, + struct passwd *pwd, + char buf[], + size_t buflen, + struct passwd **result)) { - int code; - - int (*real_getpwnam_r) (const char *, - struct passwd *, - char[], - size_t, - struct passwd **) = dlsym (RTLD_NEXT, "getpwnam_r"); - - code = real_getpwnam_r (name, pwd, buf, buflen, result); + int code = GET_REAL (getpwnam_r) (name, pwd, buf, buflen, result); pwd->pw_name = NULL; return code; } -int -getpwuid_r (uid_t uid, struct passwd *restrict pwd, char buf[], size_t buflen, struct passwd **result) +DEFINE_WRAPPER (int, getpwuid_r, (uid_t uid, + struct passwd *restrict pwd, + char buf[], + size_t buflen, + struct passwd **result)) { - int code; - - int (*real_getpwuid_r) (uid_t, - struct passwd *, - char[], - size_t, - struct passwd **) = dlsym (RTLD_NEXT, "getpwuid_r"); - - code = real_getpwuid_r (uid, pwd, buf, buflen, result); + int code = GET_REAL (getpwuid_r) (uid, pwd, buf, buflen, result); pwd->pw_name = NULL; return code; } diff --git a/glib/tests/meson.build b/glib/tests/meson.build index 8525b10d7..f74bacd20 100644 --- a/glib/tests/meson.build +++ b/glib/tests/meson.build @@ -234,14 +234,20 @@ else install_tag : 'tests', install: installed_tests_enabled) + if host_system not in ['ios', 'darwin'] + var_preload = 'LD_PRELOAD' + else + var_preload = 'DYLD_INSERT_LIBRARIES' + endif + glib_tests += { 'gutils-user-database' : { 'depends' : [], 'env' : { - 'LD_PRELOAD': getpwuid_preload.full_path() + var_preload: getpwuid_preload.full_path() }, 'installed_tests_env' : { - 'LD_PRELOAD': installed_tests_execdir / fs.name(getpwuid_preload.full_path()) + var_preload: installed_tests_execdir / fs.name(getpwuid_preload.full_path()) }, }, }