diff --git a/porting/linux/user/config/ld-musl-namespace-aarch64.ini b/porting/linux/user/config/ld-musl-namespace-aarch64.ini index 34747a703a94a30a2e7aec864333603fe5ce1ea3..4067343fcc541f79dea74c2cc7e6f17336cec0bf 100644 --- a/porting/linux/user/config/ld-musl-namespace-aarch64.ini +++ b/porting/linux/user/config/ld-musl-namespace-aarch64.ini @@ -4,3 +4,4 @@ [acquiescence] namespace.default.lib.paths = /system/lib64:/vendor/lib64:/vendor/lib64/chipsetsdk:/system/lib64/ndk:/system/lib64/chipset-pub-sdk:/system/lib64/chipset-sdk:/system/lib64/platformsdk:/system/lib64/priv-platformsdk:/system/lib64/priv-module:/system/lib64/module:/system/lib64/module/data:/system/lib64/module/multimedia:/system/lib:/vendor/lib:/system/lib/ndk:/system/lib/chipset-pub-sdk:/system/lib/chipset-sdk:/system/lib/platformsdk:/system/lib/priv-platformsdk:/system/lib/priv-module:/system/lib/module:/system/lib/module/data:/system/lib/module/multimedia:/lib64:/lib:/usr/local/lib:/usr/lib namespace.default.asan.lib.paths = /system/lib64:/system/lib64/module:/vendor/lib64:/vendor/lib64/chipsetsdk:/system/lib64/module/data:/system/lib64/module/multimedia:/system/lib:/system/lib/module:/system/lib/module/data:/system/lib/module/multimedia:/lib64:/lib:/usr/local/lib:/usr/lib + namespace.default.ignore_global_library = true \ No newline at end of file diff --git a/porting/linux/user/config/ld-musl-namespace-arm.ini b/porting/linux/user/config/ld-musl-namespace-arm.ini index 98f7a1bdb6ade47ab36ad493907d75dd7c1387b5..0c3f122bf23ded54d256686bfc063fa0f02f76ef 100644 --- a/porting/linux/user/config/ld-musl-namespace-arm.ini +++ b/porting/linux/user/config/ld-musl-namespace-arm.ini @@ -4,3 +4,4 @@ [acquiescence] namespace.default.lib.paths = /system/lib:/vendor/lib:/vendor/lib/chipsetsdk:/system/lib/ndk:/system/lib/chipset-pub-sdk:/system/lib/chipset-sdk:/system/lib/platformsdk:/system/lib/priv-platformsdk:/system/lib/priv-module:/system/lib/module:/system/lib/module/data:/system/lib/module/multimedia:/lib:/usr/local/lib:/usr/lib namespace.default.asan.lib.paths = /system/lib:/system/lib/module:/vendor/lib:/vendor/lib/chipsetsdk:/system/lib/module/data:/system/lib/module/multimedia:/lib:/usr/local/lib:/usr/lib + namespace.default.ignore_global_library = true \ No newline at end of file diff --git a/porting/linux/user/config/ld-musl-namespace-x86_64.ini b/porting/linux/user/config/ld-musl-namespace-x86_64.ini index 518e61d001bd42d2c8dd78ac48fe0bbebe2304c3..c892408c036e75528105070e74434a2aca0c5f18 100644 --- a/porting/linux/user/config/ld-musl-namespace-x86_64.ini +++ b/porting/linux/user/config/ld-musl-namespace-x86_64.ini @@ -4,3 +4,4 @@ [acquiescence] namespace.default.lib.paths = /system/lib64:/vendor/lib64:/vendor/lib64/chipsetsdk:/system/lib64/ndk:/system/lib64/chipset-pub-sdk:/system/lib64/chipset-sdk:/system/lib64/platformsdk:/system/lib64/priv-platformsdk:/system/lib64/priv-module:/system/lib64/module:/system/lib64/module/data:/system/lib64/module/multimedia:/lib64 namespace.default.asan.lib.paths = /system/lib64:/system/lib64/module:/vendor/lib64:/vendor/lib64/chipsetsdk:/system/lib64/module/data:/system/lib64/module/multimedia:/lib64 + namespace.default.ignore_global_library = true \ No newline at end of file diff --git a/porting/linux/user/ldso/dynlink.c b/porting/linux/user/ldso/dynlink.c index d0022fc9ea89f915dcf6eec3281f32feb5217d5d..5d27b1c2746b348dbfe815c36cf736cafe66d7a0 100644 --- a/porting/linux/user/ldso/dynlink.c +++ b/porting/linux/user/ldso/dynlink.c @@ -274,13 +274,15 @@ static void init_default_namespace(struct dso *app) if (env_path) ns_set_env_paths(default_ns, env_path); ns_set_lib_paths(default_ns, sys_path); ns_set_separated(default_ns, false); + ns_set_ignore_global_library(default_ns, true); app->namespace = default_ns; ns_add_dso(default_ns, app); LD_LOGD("init_default_namespace default_namespace:" "nsname: default ," "lib_paths:%{public}s ," "env_path:%{public}s ," - "separated: false.", + "separated: false ," + "ignore_global_library: true.", sys_path, env_path); return; } @@ -295,6 +297,8 @@ static void set_ns_attrs(ns_t *ns, ns_configor *conf) ns_set_separated(ns, conf->get_separated(ns->ns_name)); + ns_set_ignore_global_library(ns, conf->get_ignore_global_library(ns->ns_name)); + lib_paths = conf->get_lib_paths(ns->ns_name); if (lib_paths) ns_set_lib_paths(ns, lib_paths); @@ -647,11 +651,11 @@ static Sym *gnu_lookup(struct sym_info_pair s_info_p, uint32_t *hashtab, struct static Sym *gnu_lookup_filtered(struct sym_info_pair s_info_p, uint32_t *hashtab, struct dso *dso, struct verinfo *verinfo, uint32_t fofs, size_t fmask) { - uint32_t h1 = s_info_p.sym_h; const size_t *bloomwords = (const void *)(hashtab+4); size_t f = bloomwords[fofs & (hashtab[2]-1)]; if (!(f & fmask)) return 0; + uint32_t h1 = s_info_p.sym_h; f >>= (h1 >> hashtab[3]) % (8 * sizeof f); if (!(f & 1)) return 0; @@ -2606,6 +2610,7 @@ void __dls3(size_t *sp, size_t *auxv) /* Initial dso chain consists only of the app. */ head = tail = syms_tail = &app; + struct dso *orig_syms_tail = syms_tail; /* Donate unused parts of app and library mapping to malloc */ reclaim_gaps(&app); @@ -2751,6 +2756,9 @@ void __dls3(size_t *sp, size_t *auxv) DFX_InstallSignalHandler(); #endif errno = 0; + if (app.namespace->ignore_global_library) { + revert_syms(orig_syms_tail); + } CRTJMP((void *)aux[AT_ENTRY], argv-1); for(;;); @@ -2973,8 +2981,9 @@ static void *dlopen_impl_orig( /* If RTLD_GLOBAL was not specified, undo any new additions * to the global symbol table. This is a nop if the library was - * previously loaded and already global. */ - if (!(mode & RTLD_GLOBAL)) + * previously loaded and already global. If it is default namespace, + * we also undo any new additions to the global symbol table. */ + if (!(mode & RTLD_GLOBAL) || p->namespace->ignore_global_library) revert_syms(orig_syms_tail); /* Processing of deferred lazy relocations must not happen until diff --git a/porting/linux/user/ldso/namespace.c b/porting/linux/user/ldso/namespace.c index 28de5f31b98b705dc1ef15e0206f93cb282ee863..4f99c6a4dd65f521d261c33a6756d2b30cddcbba 100644 --- a/porting/linux/user/ldso/namespace.c +++ b/porting/linux/user/ldso/namespace.c @@ -327,6 +327,15 @@ void ns_set_separated(ns_t *ns, bool separated) LD_LOGD("ns_set_separated ns[%{public}s] separated:%{public}d.", ns->ns_name, ns->separated); } +void ns_set_ignore_global_library(ns_t *ns, bool ignore_global_library) +{ + if (!ns) { + return; + } + ns->ignore_global_library = ignore_global_library; + LD_LOGD("ns_set_ignore_global_library ns[%{public}s] ignore_global_library:%{public}d.", ns->ns_name, ns->ignore_global_library); +} + void ns_set_allowed_libs(ns_t *ns, const char *allowed_libs) { if (!ns) { diff --git a/porting/linux/user/ldso/namespace.h b/porting/linux/user/ldso/namespace.h index c395ed1261d383e7ce7227d5c2b8b4da44ed6635..461194885d710b1ccdd26be2b239dd5c606cc709 100644 --- a/porting/linux/user/ldso/namespace.h +++ b/porting/linux/user/ldso/namespace.h @@ -43,6 +43,7 @@ typedef struct _namespace_t_ { strlist *asan_permitted_paths; /* when asan is enable and separated,the same as above. */ bool separated; /* if separated */ + bool ignore_global_library; /* when true, RTLD_GLOBAL will be invalid in current ns. */ strlist *allowed_libs; /* when separated, allowed library names splited by ':'. */ dsolist *ns_dsos; /* dso list in this namespace */ struct _ns_inherit_list_ *ns_inherits; /* inherit list in this namespace */ @@ -78,6 +79,7 @@ void ns_set_asan_lib_paths(ns_t *ns, const char *asan_lib_paths); void ns_set_permitted_paths(ns_t *ns, const char *permitted_paths); void ns_set_asan_permitted_paths(ns_t *ns, const char *asan_permitted_paths); void ns_set_separated(ns_t *ns, bool separated); +void ns_set_ignore_global_library(ns_t *ns, bool ignore_global_library); void ns_set_allowed_libs(ns_t *ns, const char *allowed_libs); void ns_add_dso(ns_t *ns, struct dso *dso); void nslist_add_ns(ns_t *ns); diff --git a/porting/linux/user/ldso/ns_config.c b/porting/linux/user/ldso/ns_config.c index a46ae4390830c2a1ccdc0054535a6a6f90c788f1..30f04e66580ec786e2176cc17a7c22e4141e1ad8 100644 --- a/porting/linux/user/ldso/ns_config.c +++ b/porting/linux/user/ldso/ns_config.c @@ -361,6 +361,7 @@ static ns_configor g_configor; #define ATTR_NS_PERMITTED_PATHS "permitted.paths" /* when separated, permitted dir paths of libs, including sub dirs */ #define ATTR_NS_INHERITS "inherits" /* inherited namespace */ #define ATTR_NS_SEPARATED "separated" /* if separated */ +#define ATTR_NS_IGNORE_GLOBAL_LIBRARY "ignore_global_library" /* when true, RTLD_GLOBAL will be invalid in current ns. */ #define ATTR_ADDED_NSLIST "added.nslist" /* all namespace names except default */ #define ATTR_NS_DEFAULT "default" /* default namespace name */ #define ATTR_NS_ACQUIESCENCE "acquiescence" /* acquiescence section name */ @@ -598,7 +599,22 @@ static bool config_get_separated(const char *ns_name) if (val && !strcmp("true", val)) return true; return false; /* default false */ } - +/* get ignore_global_library */ +static bool config_get_ignore_global_library(const char *ns_name) +{ + if (ns_name == NULL) { + return false; + } + config_key_join(ATTR_NS_PREFIX, true); + config_key_join(".", false); + config_key_join(ns_name, false); + config_key_join(".", false); + char *key = config_key_join(ATTR_NS_IGNORE_GLOBAL_LIBRARY, false); + char *val = config_get_value(key); + strlwc(val); + if (val && !strcmp("true", val)) return true; + return false; /* default false */ +} /* get allowed libs */ static char *config_get_allowed_libs(const char *ns_name) { @@ -648,6 +664,7 @@ ns_configor *configor_init() g_configor.get_permitted_paths = config_get_permitted_paths; g_configor.get_asan_permitted_paths = config_get_asan_permitted_paths; g_configor.get_separated = config_get_separated; + g_configor.get_ignore_global_library = config_get_ignore_global_library; g_configor.get_inherits = config_get_inherits; g_configor.get_allowed_libs = config_get_allowed_libs; g_configor.get_inherit_shared_libs = config_get_inherit_shared_libs; diff --git a/porting/linux/user/ldso/ns_config.h b/porting/linux/user/ldso/ns_config.h index a45f9c91b0f1f8fb2095d8452a09b11732f8b0e9..18aa2670c7c49fc9f9a0487337a1d3fb526906be 100644 --- a/porting/linux/user/ldso/ns_config.h +++ b/porting/linux/user/ldso/ns_config.h @@ -62,6 +62,7 @@ typedef struct _ns_configor_ { char *(*get_permitted_paths)(const char *ns_name); char *(*get_asan_permitted_paths)(const char *ns_name); bool (*get_separated)(const char *ns_name); + bool (*get_ignore_global_library)(const char *ns_name); strlist *(*get_inherits)(const char *ns_name); char *(*get_allowed_libs)(const char *ns_name); char *(*get_inherit_shared_libs)(const char *ns_name, const char *inherited_ns_name);