Page MenuHomeFreeBSD

D26352.id93703.diff
No OneTemporary

D26352.id93703.diff

diff --git a/libexec/rtld-elf/rtld.1 b/libexec/rtld-elf/rtld.1
--- a/libexec/rtld-elf/rtld.1
+++ b/libexec/rtld-elf/rtld.1
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 2, 2021
+.Dd August 15, 2021
.Dt RTLD 1
.Os
.Sh NAME
@@ -143,6 +143,24 @@
.Nm
will print a table containing all relocations before symbol
binding and relocation.
+.It Ev LD_DYNAMIC_WEAK
+If set, use the ELF standard-compliant symbol lookup behavior:
+resolve to the first found symbol definition.
+.Pp
+By default,
+.Fx
+provides the non-standard symbol lookup behavior:
+when a weak symbol definition is found, remember the definition and
+keep searching in the remaining shared objects for a non-weak definition.
+If found, the non-weak definition is preferred, otherwise the remembered
+weak definition is returned.
+.Pp
+Symbols exported by dynamic linker itself (see
+.Xr dlfcn 3 )
+are always resolved using
+.Fx
+rules regardless of the presence of the variable.
+This variable is unset for set-user-ID and set-group-ID programs.
.It Ev LD_LIBMAP
A library replacement list in the same format as
.Xr libmap.conf 5 .
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -209,6 +209,8 @@
bool ld_bind_not; /* Disable PLT update */
static char *ld_bind_now; /* Environment variable for immediate binding */
static char *ld_debug; /* Environment variable for debugging */
+static bool ld_dynamic_weak = true; /* True if non-weak definition overrides
+ weak definition */
static char *ld_library_path; /* Environment variable for search path */
static char *ld_library_dirs; /* Environment variable for library descriptors */
static char *ld_preload; /* Environment variable for libraries to
@@ -583,7 +585,7 @@
unsetenv(_LD("LIBMAP_DISABLE")) || unsetenv(_LD("BIND_NOT")) ||
unsetenv(_LD("DEBUG")) || unsetenv(_LD("ELF_HINTS_PATH")) ||
unsetenv(_LD("LOADFLTR")) || unsetenv(_LD("LIBRARY_PATH_RPATH")) ||
- unsetenv(_LD("PRELOAD_FDS"))) {
+ unsetenv(_LD("PRELOAD_FDS")) || unsetenv(_LD("DYNAMIC_WEAK"))) {
_rtld_error("environment corrupt; aborting");
rtld_die();
}
@@ -591,6 +593,7 @@
ld_debug = getenv(_LD("DEBUG"));
if (ld_bind_now == NULL)
ld_bind_not = getenv(_LD("BIND_NOT")) != NULL;
+ ld_dynamic_weak = getenv(_LD("DYNAMIC_WEAK")) == NULL;
libmap_disable = getenv(_LD("LIBMAP_DISABLE")) != NULL;
libmap_override = getenv(_LD("LIBMAP"));
ld_library_path = getenv(_LD("LIBRARY_PATH"));
@@ -610,7 +613,7 @@
}
dangerous_ld_env = libmap_disable || (libmap_override != NULL) ||
(ld_library_path != NULL) || (ld_preload != NULL) ||
- (ld_elf_hints_path != NULL) || ld_loadfltr;
+ (ld_elf_hints_path != NULL) || ld_loadfltr || ld_dynamic_weak;
ld_tracing = getenv(_LD("TRACE_LOADED_OBJECTS"));
ld_utrace = getenv(_LD("UTRACE"));
@@ -3673,11 +3676,12 @@
continue;
res = symlook_obj(&req, obj);
if (res == 0) {
- if (def == NULL ||
- ELF_ST_BIND(req.sym_out->st_info) != STB_WEAK) {
+ if (def == NULL || (ld_dynamic_weak &&
+ ELF_ST_BIND(req.sym_out->st_info) != STB_WEAK)) {
def = req.sym_out;
defobj = req.defobj_out;
- if (ELF_ST_BIND(def->st_info) != STB_WEAK)
+ if (!ld_dynamic_weak ||
+ ELF_ST_BIND(def->st_info) != STB_WEAK)
break;
}
}
@@ -3686,6 +3690,8 @@
* Search the dynamic linker itself, and possibly resolve the
* symbol from there. This is how the application links to
* dynamic linker services such as dlopen.
+ * Note that we ignore ld_dynamic_weak == false case,
+ * always overriding weak symbols by rtld definitions.
*/
if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
res = symlook_obj(&req, &obj_rtld);
@@ -4288,10 +4294,10 @@
symlook_init_from_req(&req1, req);
/* Search all objects loaded at program start up. */
- if (req->defobj_out == NULL ||
- ELF_ST_BIND(req->sym_out->st_info) == STB_WEAK) {
+ if (req->defobj_out == NULL || (ld_dynamic_weak &&
+ ELF_ST_BIND(req->sym_out->st_info) == STB_WEAK)) {
res = symlook_list(&req1, &list_main, donelist);
- if (res == 0 && (req->defobj_out == NULL ||
+ if (res == 0 && (!ld_dynamic_weak || req->defobj_out == NULL ||
ELF_ST_BIND(req1.sym_out->st_info) != STB_WEAK)) {
req->sym_out = req1.sym_out;
req->defobj_out = req1.defobj_out;
@@ -4301,8 +4307,8 @@
/* Search all DAGs whose roots are RTLD_GLOBAL objects. */
STAILQ_FOREACH(elm, &list_global, link) {
- if (req->defobj_out != NULL &&
- ELF_ST_BIND(req->sym_out->st_info) != STB_WEAK)
+ if (req->defobj_out != NULL && (!ld_dynamic_weak ||
+ ELF_ST_BIND(req->sym_out->st_info) != STB_WEAK))
break;
res = symlook_list(&req1, &elm->obj->dagmembers, donelist);
if (res == 0 && (req->defobj_out == NULL ||
@@ -4351,8 +4357,8 @@
/* Search all dlopened DAGs containing the referencing object. */
STAILQ_FOREACH(elm, &refobj->dldags, link) {
- if (req->sym_out != NULL &&
- ELF_ST_BIND(req->sym_out->st_info) != STB_WEAK)
+ if (req->sym_out != NULL && (!ld_dynamic_weak ||
+ ELF_ST_BIND(req->sym_out->st_info) != STB_WEAK))
break;
res = symlook_list(&req1, &elm->obj->dagmembers, &donelist);
if (res == 0 && (req->sym_out == NULL ||
@@ -4397,10 +4403,11 @@
continue;
symlook_init_from_req(&req1, req);
if ((res = symlook_obj(&req1, elm->obj)) == 0) {
- if (def == NULL || ELF_ST_BIND(req1.sym_out->st_info) != STB_WEAK) {
+ if (def == NULL || (ld_dynamic_weak &&
+ ELF_ST_BIND(req1.sym_out->st_info) != STB_WEAK)) {
def = req1.sym_out;
defobj = req1.defobj_out;
- if (ELF_ST_BIND(def->st_info) != STB_WEAK)
+ if (!ld_dynamic_weak || ELF_ST_BIND(def->st_info) != STB_WEAK)
break;
}
}
@@ -4435,10 +4442,11 @@
if (n->obj == NULL ||
(res = symlook_list(&req1, &n->obj->dagmembers, dlp)) != 0)
continue;
- if (def == NULL || ELF_ST_BIND(req1.sym_out->st_info) != STB_WEAK) {
+ if (def == NULL || (ld_dynamic_weak &&
+ ELF_ST_BIND(req1.sym_out->st_info) != STB_WEAK)) {
def = req1.sym_out;
defobj = req1.defobj_out;
- if (ELF_ST_BIND(def->st_info) != STB_WEAK)
+ if (!ld_dynamic_weak || ELF_ST_BIND(def->st_info) != STB_WEAK)
break;
}
}

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 3, 1:07 AM (10 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30703093
Default Alt Text
D26352.id93703.diff (6 KB)

Event Timeline