From 4058a11e0b1e6ce9e16ce63dd7c970379c0587a2 Mon Sep 17 00:00:00 2001 From: Simon McVittie <smcv@collabora.com> Date: Wed, 8 Nov 2017 13:56:58 +0000 Subject: [PATCH] Include a pointer to the namespace in the capsule structure Signed-off-by: Simon McVittie <smcv@collabora.com> --- capsule/capsule-dlmopen.c | 6 +-- capsule/capsule-init.c | 80 +++++++++++++++++++------------------- capsule/capsule-private.h | 10 ++++- capsule/capsule-wrappers.c | 10 ++--- capsule/capsule.h | 1 - 5 files changed, 57 insertions(+), 50 deletions(-) diff --git a/capsule/capsule-dlmopen.c b/capsule/capsule-dlmopen.c index d6fd6208c..3ddf18b9c 100644 --- a/capsule/capsule-dlmopen.c +++ b/capsule/capsule-dlmopen.c @@ -276,9 +276,7 @@ capsule_load (const capsule cap, capsule other = ptr_list_nth_ptr( _capsule_list, n ); // this subcapsule is for a different prefix. skip it: - //DEBUG( DEBUG_CAPSULE, "checking prefix match: %p vs %p", - // cap->prefix, other->meta->active_prefix ); - if( strcmp( cap->prefix, other->prefix ) ) + if( cap->ns != other->ns ) continue; // we found a pre-allocated Lmid_t. Use it: @@ -294,7 +292,7 @@ capsule_load (const capsule cap, if( !ld_libs_init( &ldlibs, (const char **) cap->meta->combined_exclude, - cap->meta->active_prefix, debug_flags, errcode, error ) ) + cap->ns->prefix, debug_flags, errcode, error ) ) return NULL; // ================================================================== diff --git a/capsule/capsule-init.c b/capsule/capsule-init.c index 568af1c20..bd243fc55 100644 --- a/capsule/capsule-init.c +++ b/capsule/capsule-init.c @@ -22,13 +22,11 @@ "struct _capsule %p" "\n" \ "{" "\n" \ " void *dl_handle; %p" "\n" \ - " char *prefix; %s" "\n" \ " capsule_metadata *meta; %p" "\n" \ " {" "\n" \ " Lmid_t namespace; %ld" "\n" \ " const char *soname; %s" "\n" \ " const char *default_prefix; %s" "\n" \ - " char *active_prefix; %s" "\n" \ " const char **exclude; %p" "\n" \ " const char **export; %p" "\n" \ " const char **nowrap; %p" "\n" \ @@ -36,29 +34,25 @@ " char **combined_export; %p" "\n" \ " char **combined_nowrap; %p" "\n" \ " };" "\n" \ + " capsule_namespace *ns; %p" "\n" \ + " {" "\n" \ + " char *prefix; %s" "\n" \ + " };" "\n" \ "};" "\n", \ cap , \ cap->dl_handle , \ - cap->prefix , \ cap->meta , \ cap->meta->namespace , \ cap->meta->soname , \ cap->meta->default_prefix , \ - cap->meta->active_prefix , \ cap->meta->exclude , \ cap->meta->export , \ cap->meta->nowrap , \ cap->meta->combined_exclude , \ cap->meta->combined_export , \ - cap->meta->combined_nowrap ); }) - -typedef struct _capsule_namespace -{ - const char *prefix; - ptr_list *exclusions; - ptr_list *exports; - ptr_list *nowrap; -} capsule_namespace; + cap->meta->combined_nowrap , \ + cap->ns , \ + cap->ns->prefix ); }) static ptr_list *namespaces = NULL; @@ -77,11 +71,19 @@ static int str_equal (const void *a, const void *b) return strcmp( (char *)a, (char *)b ) == 0; } +static const char *get_prefix_nocopy (const char *dflt, const char *soname); + static capsule_namespace * -get_namespace (const char *prefix) +get_namespace (const char *default_prefix, const char *soname) { + const char *prefix = get_prefix_nocopy( default_prefix, soname ); capsule_namespace *ns; + // Normalize so that libraries with prefix NULL, "" or "/" are all + // treated as equivalent + if( prefix == NULL || prefix[0] == '\0' ) + prefix = "/"; + if( namespaces == NULL ) namespaces = ptr_list_alloc( 4 ); @@ -96,7 +98,7 @@ get_namespace (const char *prefix) } ns = calloc( 1, sizeof(capsule_namespace) ); - ns->prefix = prefix; + ns->prefix = strdup( prefix ); ns->exclusions = ptr_list_alloc( 4 ); ns->exports = ptr_list_alloc( 4 ); ns->nowrap = ptr_list_alloc( 4 ); @@ -166,22 +168,16 @@ get_capsule_metadata (struct link_map *map, const char *only) meta->namespace = LM_ID_NEWLM; meta->closed = 0; - if( meta->active_prefix ) - free( meta->active_prefix ); - - meta->active_prefix = - capsule_get_prefix( meta->default_prefix, meta->soname ); - cap = meta->handle; if( cap == NULL ) { cap = xcalloc( 1, sizeof(struct _capsule) ); + cap->ns = get_namespace( meta->default_prefix, meta->soname ); DEBUG( DEBUG_CAPSULE, "Creating new capsule %p for metadata %p (%s … %s)", - cap, meta, meta->active_prefix, meta->soname ); + cap, meta, cap->ns->prefix, meta->soname ); cap->meta = meta; - cap->prefix = meta->active_prefix; cap->seen.all = ptr_list_alloc( 32 ); cap->seen.some = ptr_list_alloc( 32 ); meta->handle = cap; @@ -190,7 +186,7 @@ get_capsule_metadata (struct link_map *map, const char *only) DEBUG( DEBUG_CAPSULE, "found metadata for %s … %s at %p (capsule: %p)", - meta->active_prefix, meta->soname, meta, cap ); + cap->ns->prefix, meta->soname, meta, cap ); break; } } @@ -280,11 +276,9 @@ update_metadata (const char *match) if( !cap ) continue; - capsule_namespace *ns = get_namespace( cap->prefix ); - - add_new_strings_to_ptrlist( ns->exclusions, cap->meta->exclude ); - add_new_strings_to_ptrlist( ns->exports, cap->meta->export ); - add_new_strings_to_ptrlist( ns->nowrap, cap->meta->nowrap ); + add_new_strings_to_ptrlist( cap->ns->exclusions, cap->meta->exclude ); + add_new_strings_to_ptrlist( cap->ns->exports, cap->meta->export ); + add_new_strings_to_ptrlist( cap->ns->nowrap, cap->meta->nowrap ); } // now squash the meta data ptr_lists into char** that @@ -296,15 +290,13 @@ update_metadata (const char *match) if( !cap ) continue; - capsule_namespace *ns = get_namespace( cap->prefix ); - free_strv( cap->meta->combined_exclude ); free_strv( cap->meta->combined_export ); free_strv( cap->meta->combined_nowrap ); - cap->meta->combined_exclude = cook_list( ns->exclusions ); - cap->meta->combined_export = cook_list( ns->exports ); - cap->meta->combined_nowrap = cook_list( ns->nowrap ); + cap->meta->combined_exclude = cook_list( cap->ns->exclusions ); + cap->meta->combined_export = cook_list( cap->ns->exports ); + cap->meta->combined_nowrap = cook_list( cap->ns->nowrap ); } } @@ -340,11 +332,22 @@ static void __attribute__ ((constructor)) _init_capsule (void) char * capsule_get_prefix (const char *dflt, const char *soname) +{ + const char *prefix = get_prefix_nocopy( dflt, soname ); + + if (prefix != NULL) + return xstrdup( prefix ); + + return NULL; +} + +static const char * +get_prefix_nocopy (const char *dflt, const char *soname) { char env_var[PATH_MAX] = CAP_ENV_PREFIX; const size_t offs = strlen( CAP_ENV_PREFIX ); size_t x = 0; - char *prefix = NULL; + const char *prefix = NULL; for( ; (x < strlen(soname)) && (x + offs < PATH_MAX); x++ ) { @@ -360,7 +363,7 @@ capsule_get_prefix (const char *dflt, const char *soname) if( (prefix = secure_getenv( &env_var[0] )) ) { DEBUG( DEBUG_SEARCH, "Capsule prefix is %s: %s", &env_var[0], prefix ); - return strdup( prefix ); + return prefix; } DEBUG( DEBUG_CAPSULE, "checking %s\n", CAP_ENV_PREFIX "PREFIX" ); @@ -368,13 +371,13 @@ capsule_get_prefix (const char *dflt, const char *soname) { DEBUG( DEBUG_SEARCH, "Capsule prefix is "CAP_ENV_PREFIX"PREFIX: %s", prefix ); - return strdup( prefix ); + return prefix; } if( dflt ) { DEBUG( DEBUG_SEARCH, "Capsule prefix is built-in: %s", dflt ); - return strdup( dflt ); + return dflt; } DEBUG( DEBUG_SEARCH, "Capsule prefix is missing" ); @@ -471,7 +474,6 @@ capsule_close (capsule cap) CLEAR( free_strv, meta->combined_exclude ); CLEAR( free_strv, meta->combined_export ); CLEAR( free_strv, meta->combined_nowrap ); - CLEAR( free , meta->active_prefix ); meta->handle = NULL; CLEAR( ptr_list_free, cap->seen.all ); diff --git a/capsule/capsule-private.h b/capsule/capsule-private.h index 5ef4865a3..4640fa2da 100644 --- a/capsule/capsule-private.h +++ b/capsule/capsule-private.h @@ -6,13 +6,21 @@ typedef void * (*dlsymfunc) (void *handle, const char *symbol); typedef void * (*dlopnfunc) (const char *file, int flags); +typedef struct _capsule_namespace +{ + const char *prefix; + ptr_list *exclusions; + ptr_list *exports; + ptr_list *nowrap; +} capsule_namespace; + struct _capsule { void *dl_handle; - const char *prefix; capsule_item *relocations; struct { ptr_list *all; ptr_list *some; } seen; capsule_metadata *meta; + capsule_namespace *ns; }; extern ptr_list *_capsule_list; diff --git a/capsule/capsule-wrappers.c b/capsule/capsule-wrappers.c index e943af803..855a5fe17 100644 --- a/capsule/capsule-wrappers.c +++ b/capsule/capsule-wrappers.c @@ -182,12 +182,12 @@ capsule_shim_dlopen(const capsule cap, const char *file, int flag) DEBUG( DEBUG_WRAPPERS|DEBUG_DLFUNC, "dlopen(%s, %x) wrapper: LMID: %ld; prefix: %s;", - file, flag, cap->meta->namespace, cap->meta->active_prefix ); + file, flag, cap->meta->namespace, cap->ns->prefix ); - if( cap->prefix && strcmp(cap->prefix, "/") ) + if( cap->ns->prefix && strcmp(cap->ns->prefix, "/") ) { if( !ld_libs_init( &ldlibs, (const char **)cap->meta->combined_exclude, - cap->prefix, debug_flags, &code, &errors ) ) + cap->ns->prefix, debug_flags, &code, &errors ) ) { DEBUG( DEBUG_LDCACHE|DEBUG_WRAPPERS|DEBUG_DLFUNC, "Initialising ld_libs data failed: error %d: %s", @@ -198,7 +198,7 @@ capsule_shim_dlopen(const capsule cap, const char *file, int flag) if( !ld_libs_load_cache( &ldlibs, "/etc/ld.so.cache", &code, &errors ) ) { DEBUG( DEBUG_LDCACHE|DEBUG_WRAPPERS|DEBUG_DLFUNC, - "Loading ld.so.cache from %s: error %d: %s", cap->prefix, + "Loading ld.so.cache from %s: error %d: %s", cap->ns->prefix, code, errors ); goto cleanup; } @@ -208,7 +208,7 @@ capsule_shim_dlopen(const capsule cap, const char *file, int flag) { DEBUG( DEBUG_SEARCH|DEBUG_WRAPPERS|DEBUG_DLFUNC, "Not found: %s under %s: error %d: %s", - file, cap->prefix, code, errors ); + file, cap->ns->prefix, code, errors ); goto cleanup; } diff --git a/capsule/capsule.h b/capsule/capsule.h index b545412a4..7ace8e424 100644 --- a/capsule/capsule.h +++ b/capsule/capsule.h @@ -102,7 +102,6 @@ struct _capsule_metadata const int capsule_abi; /*< private >*/ int closed; - char *active_prefix; char **combined_exclude; char **combined_export; char **combined_nowrap; -- GitLab