On 19/04/2025 13:29, Konstantin Belousov wrote:
On Sat, Apr 19, 2025 at 01:25:28PM +0300, Andriy Gapon wrote:
On 19/04/2025 12:39, Andriy Gapon wrote:
From a quick look at the code, should we try to resolve the symbol in
refobj itself when it's marked with deepbind?
Oh, and it looks like objects loaded under the "deepbind" object (e.g.,
needed objects) may not be aware that they are in the deepbind sub-tree?
But should they?
That's a right question.
I have been reading about RTLD_DEEPBIND and Solaris flags like RTLD_GROUP, etc
at the same time. I guess that's why some things got "fused" in my mind. So, I
started believing that the concept of shared object dependency groups also
applies to RTLD_DEEPBIND.
But that's not documented to be so, at least, in the documentation that I could
find. There are some in-depth documentation on Solaris run-time linker and its
handling of various options. But for Linux RTLD_DEEPBIND I could find only
manual page references and they only say that deep-binding applies to to the
object being dlopen-ed.
I am not sure if that's how the option actually works on Linux.
I allow for possibility that the manual pages omit (or, at least, do not spell
out) some details for brevity.
In any case, I believe that the proposed patch is correct.
But I think that it would not help in my case.
I have: mdb -[dlopen]-> dtrace.so -[needs]-> libdtrace.so.
And it's a symbol in libdtrace.so that gets resolved to mdb instead of
libdtrace.so itself.
The patch would affect how symbols in dtrace.so are resolved if I understand
correctly.
Lets start with some minimal intrusive change:
commit b4f4feb883a1be1d4ca3867f49baa20ce0c13d8d
Author: Konstantin Belousov <k...@freebsd.org>
Date: Sat Apr 19 13:26:58 2025 +0300
rtld: symbolic and deepbind are equivalent for the refobj
Reported by: avg
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 2346c6eae9f6..8ea6afb43752 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -4679,12 +4679,13 @@ symlook_default(SymLook *req, const Obj_Entry *refobj)
*/
res = symlook_obj(&req1, refobj);
if (res == 0 && (refobj->symbolic ||
- ELF_ST_VISIBILITY(req1.sym_out->st_other) == STV_PROTECTED)) {
+ ELF_ST_VISIBILITY(req1.sym_out->st_other) == STV_PROTECTED ||
+ refobj->deepbind)) {
req->sym_out = req1.sym_out;
req->defobj_out = req1.defobj_out;
assert(req->defobj_out != NULL);
}
- if (refobj->symbolic || req->defobj_out != NULL)
+ if (refobj->symbolic || req->defobj_out != NULL || refobj->deepbind)
donelist_check(&donelist, refobj);
if (!refobj->deepbind)
--
Andriy Gapon