Skip to content
Snippets Groups Projects
Commit 14f97c6a authored by Vivek Das Mohapatra's avatar Vivek Das Mohapatra
Browse files

Variant of capsule_relocate that allows external DSOs to be ignored

This will be used to do special-case dlopen wrapping outside the capsule
parent 6d4cf82e
No related branches found
No related tags found
1 merge request!311Build capsule-capture-libs from a bundled copy of libcapsule
...@@ -62,6 +62,21 @@ process_phdr (struct dl_phdr_info *info, ...@@ -62,6 +62,21 @@ process_phdr (struct dl_phdr_info *info,
return ret; return ret;
} }
static int
dso_is_blacklisted (const char *path, const char **blacklist)
{
char **soname;
if( blacklist == NULL )
return 0;
for( soname = (char **) blacklist; soname && *soname; soname++ )
if( soname_matches_path( *soname, path ) )
return 1;
return 0;
}
// first level of the callback: all we're doing here is skipping over // first level of the callback: all we're doing here is skipping over
// any program headers that (for whatever reason) we decide we're not // any program headers that (for whatever reason) we decide we're not
// interested in. // interested in.
...@@ -71,16 +86,20 @@ static int ...@@ -71,16 +86,20 @@ static int
relocate_cb (struct dl_phdr_info *info, size_t size, void *data) relocate_cb (struct dl_phdr_info *info, size_t size, void *data)
{ {
relocation_data_t *rdata = data; relocation_data_t *rdata = data;
const char *dso_path = *info->dlpi_name ? info->dlpi_name : "-elf-";
DEBUG( DEBUG_RELOCS, "processing %s", DEBUG( DEBUG_RELOCS, "processing %s", dso_path );
*info->dlpi_name ? info->dlpi_name : "-elf-" );
if( dso_is_blacklisted( dso_path, rdata->blacklist ) )
return 0;
return process_phdr( info, size, rdata ); return process_phdr( info, size, rdata );
} }
int capsule_relocate (const capsule cap, static int relocate (const capsule cap,
capsule_item *relocations, capsule_item *relocations,
char **error) const char **dso_blacklist,
char **error)
{ {
relocation_data_t rdata = { 0 }; relocation_data_t rdata = { 0 };
capsule_item *map; capsule_item *map;
...@@ -88,9 +107,21 @@ int capsule_relocate (const capsule cap, ...@@ -88,9 +107,21 @@ int capsule_relocate (const capsule cap,
const char *mmap_error = NULL; const char *mmap_error = NULL;
int rval = 0; int rval = 0;
if( cap->relocations != NULL && cap->relocations != relocations )
{
DEBUG( DEBUG_RELOCS,
"relocations array updated: "
"if unintentional capsule may behave unpredictably" );
}
if( relocations != NULL )
cap->relocations = relocations;
// load the relevant metadata into the callback argument:
rdata.debug = debug_flags; rdata.debug = debug_flags;
rdata.error = NULL; rdata.error = NULL;
rdata.relocs = relocations; rdata.relocs = cap->relocations;
rdata.blacklist = dso_blacklist;
rdata.mmap_info = load_mmap_info( &mmap_errno, &mmap_error ); rdata.mmap_info = load_mmap_info( &mmap_errno, &mmap_error );
if( mmap_errno || mmap_error ) if( mmap_errno || mmap_error )
...@@ -102,7 +133,6 @@ int capsule_relocate (const capsule cap, ...@@ -102,7 +133,6 @@ int capsule_relocate (const capsule cap,
"relocation will be unable to handle relro linked libraries" ); "relocation will be unable to handle relro linked libraries" );
} }
cap->relocations = relocations;
// no source dl handle means we must have a pre-populated // no source dl handle means we must have a pre-populated
// map of shim-to-real function pointers in `relocations', // map of shim-to-real function pointers in `relocations',
// otherwise populate the map using dlsym(): // otherwise populate the map using dlsym():
...@@ -146,3 +176,18 @@ int capsule_relocate (const capsule cap, ...@@ -146,3 +176,18 @@ int capsule_relocate (const capsule cap,
return rval; return rval;
} }
int
capsule_relocate (const capsule cap, capsule_item *relocations, char **error)
{
return relocate( cap, relocations, NULL, error );
}
int
capsule_relocate_restricted (const capsule cap,
capsule_item *relocations,
const char **dso_blacklist,
char **error)
{
return relocate( cap, relocations, dso_blacklist, error );
}
...@@ -120,6 +120,45 @@ int capsule_relocate (const capsule capsule, ...@@ -120,6 +120,45 @@ int capsule_relocate (const capsule capsule,
capsule_item *relocations, capsule_item *relocations,
char **error); char **error);
/**
* capsule_relocate_restricted:
* @capsule: a #capsule handle as returned by capsule_init()
* @relocations: (array zero-terminated=1): Array of capsule_item
* specifying which symbols to export, terminated by a
* #capsule_item whose @name is %NULL
* @dso_blacklist: (array zero-terminated=1) (optional): Array of sonames
* which should not have their GOT entries updated.
* @error: (out) (transfer full) (optional): location in which to store
* an error message on failure, or %NULL to ignore.
* Free with free().
*
* Returns: 0 on success, non-zero on failure.
*
* @source is typically the value returned by a successful capsule_load()
* call (although a handle returned by dlmopen() would also be reasonable).
*
* The #capsule_item entries in @relocations need only specify the symbol
* name: The shim and real fields will be populated automatically if they
* are not pre-filled (this is the normal use case, as it would be unusual
* to know these value in advance).
*
* This function updates the GOT entries in all DSOs outside the capsule
* _except_ those listed in @dso_blacklist: When they call any function
* listed in @relocations they invoke the copy of that function inside
* the capsule. These sonames should be of the form "libfoo.so.X"
* or "libfoo.so". You may specify further minor version numbers in the
* usual "libfoo.so.X.Y" format if you wish.
*
* In the unlikely event that an error message is returned in @error it is the
* caller's responsibility to free() it.
*/
_CAPSULE_PUBLIC
int capsule_relocate_restricted (const capsule cap,
capsule_item *relocations,
const char **dso_blacklist,
char **error);
/** /**
* capsule_load: * capsule_load:
* @capsule: a #capsule handle as returned by capsule_init() * @capsule: a #capsule handle as returned by capsule_init()
......
...@@ -35,6 +35,7 @@ typedef struct ...@@ -35,6 +35,7 @@ typedef struct
int debug; int debug;
char *error; char *error;
mmapinfo *mmap_info; mmapinfo *mmap_info;
const char **blacklist;
} relocation_data_t; } relocation_data_t;
typedef int (*relocate_cb_t)(const void *start, typedef int (*relocate_cb_t)(const void *start,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment