RTLD_DEEPBIND: make lookup not just symbolic, but walk all refobj' DAGs

before starting the walk over the global list.  Effectively we visit
needed objects first as well, instead of just the object itself.
This seems to better match the semantic offered by the glibc flag.

Reported by:	kevans
PR:	275393
Reviewed by:	kevans
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D42841
This commit is contained in:
Konstantin Belousov 2023-11-29 20:30:59 +02:00
parent c93be3079b
commit 9daf6cd0f4
2 changed files with 7 additions and 2 deletions

View file

@ -3755,7 +3755,7 @@ dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags,
if (!obj->init_done) {
/* We loaded something new and have to init something. */
if ((lo_flags & RTLD_LO_DEEPBIND) != 0)
obj->symbolic = true;
obj->deepbind = true;
result = 0;
if ((lo_flags & (RTLD_LO_EARLY | RTLD_LO_IGNSTLS)) == 0 &&
obj->static_tls && !allocate_tls_offset(obj)) {
@ -4581,7 +4581,8 @@ symlook_default(SymLook *req, const Obj_Entry *refobj)
if (refobj->symbolic || req->defobj_out != NULL)
donelist_check(&donelist, refobj);
symlook_global(req, &donelist);
if (!refobj->deepbind)
symlook_global(req, &donelist);
/* Search all dlopened DAGs containing the referencing object. */
STAILQ_FOREACH(elm, &refobj->dldags, link) {
@ -4597,6 +4598,9 @@ symlook_default(SymLook *req, const Obj_Entry *refobj)
}
}
if (refobj->deepbind)
symlook_global(req, &donelist);
/*
* Search the dynamic linker itself, and possibly resolve the
* symbol from there. This is how the application links to

View file

@ -240,6 +240,7 @@ typedef struct Struct_Obj_Entry {
bool ver_checked : 1; /* True if processed by rtld_verify_object_versions */
bool textrel : 1; /* True if there are relocations to text seg */
bool symbolic : 1; /* True if generated with "-Bsymbolic" */
bool deepbind : 1; /* True if loaded with RTLD_DEEPBIND" */
bool bind_now : 1; /* True if all relocations should be made first */
bool traced : 1; /* Already printed in ldd trace output */
bool jmpslots_done : 1; /* Already have relocated the jump slots */