Skip to content
Snippets Groups Projects
Commit ac3f0295 authored by Simon McVittie's avatar Simon McVittie
Browse files

ld-libs: Always clear ldlibs->needed entry if ld_lib_open() fails


This is what was documented to happen.

Previously, we did not clear the entry if we failed to open the
library fd, or if we succeeded but the library was "unacceptable"
(wrong ELF class or machine tag). Normally this results in a minor
memory leak, and a fd leak if the library is "unacceptable".

However, when called from search_ldcache_cb(), it's particularly
important that we do this, because search_ldcache() uses the state
of the fd field - valid fd or not - to check whether ld_lib_open()
succeeded.

One practical symptom is that if your container has an x86_64
libfoo.so.0 that compares newer than the provider's libfoo.so.0,
and does not have an i386 libfoo.so.0, then capsule-capture-libs
would unexpectedly not capture the i386 libfoo.so.0 from the provider
either.

Signed-off-by: default avatarSimon McVittie <smcv@collabora.com>
parent c92949c3
No related branches found
No related tags found
1 merge request!311Build capsule-capture-libs from a bundled copy of libcapsule
......@@ -338,7 +338,10 @@ ld_lib_open (ld_libs *ldlibs, const char *name, int i, int *code, char **message
acceptable );
if( !acceptable )
{
clear_needed( &ldlibs->needed[i] );
return 0;
}
acceptable = !target_is_ourself( ldlibs, i );
......@@ -363,6 +366,7 @@ ld_lib_open (ld_libs *ldlibs, const char *name, int i, int *code, char **message
_capsule_set_error( code, message, errsv,
"Cannot open \"%s\": %s",
ldlibs->needed[i].path, strerror( errsv ) );
clear_needed( &ldlibs->needed[i] );
return 0;
}
}
......@@ -407,7 +411,18 @@ search_ldcache_cb (const char *name, // name of the DSO in the ldcache
// needed[idx] slot if successful, and reset it ready for
// another attempt if it fails.
// TODO: Can we propagate error information?
return ld_lib_open( target->ldlibs, name, idx, NULL, NULL );
if( !ld_lib_open( target->ldlibs, name, idx, NULL, NULL ) )
{
// search_ldcache() relies on fd >= 0 iff we succeeded
assert( target->ldlibs->needed[idx].fd < 0 );
assert( target->ldlibs->needed[idx].name == NULL );
return 0;
}
// search_ldcache() relies on fd >= 0 iff we succeeded
assert( target->ldlibs->needed[idx].fd >= 0 );
assert( target->ldlibs->needed[idx].name != NULL );
return 1;
}
return 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment