Commit ac3f0295 authored by Simon McVittie's avatar Simon McVittie

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: Simon McVittie's avatarSimon McVittie <smcv@collabora.com>
parent c92949c3
Pipeline #11018 passed with stage
in 7 minutes and 38 seconds
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment