diff mbox series

[v3,04/32] elf: Eliminate second loop in find_version in dl-version.c

Message ID ff5ca6d28edb1c1ea42ad16bc261e282534c3264.1701944612.git.fweimer@redhat.com
State New
Headers show
Series RELRO linkmaps | expand

Commit Message

Florian Weimer Dec. 7, 2023, 10:31 a.m. UTC
The first loop iterates through all objects in the namespace
because _dl_check_map_versions is called after the loaded
objects have been added to the list.  (This list is not limited
by symbol search scope.)

Turn the assert in _dl_check_map_versions into a proper error
because it can be triggered by inconsistent variants of shared
objects.
---
 elf/dl-version.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

Comments

Joseph Myers Feb. 19, 2024, 10:17 p.m. UTC | #1
On Thu, 7 Dec 2023, Florian Weimer wrote:

> Turn the assert in _dl_check_map_versions into a proper error
> because it can be triggered by inconsistent variants of shared
> objects.

What's involved in such "inconsistent variants of shared objects"?  I feel 
like such an error really ought to have an actual test in the glibc 
testsuite (even if we don't have many tests for dynamic linker error 
handling at present), but failing that, more details in the commit message 
of what's needed to result in that error.
diff mbox series

Patch

diff --git a/elf/dl-version.c b/elf/dl-version.c
index 5b8693de04..b3b2160ac8 100644
--- a/elf/dl-version.c
+++ b/elf/dl-version.c
@@ -31,21 +31,17 @@  __attribute ((always_inline))
 find_needed (const char *name, struct link_map *map)
 {
   struct link_map *tmap;
-  unsigned int n;
 
   for (tmap = GL(dl_ns)[map->l_ns]._ns_loaded; tmap != NULL;
        tmap = tmap->l_next)
     if (_dl_name_match_p (name, tmap))
       return tmap;
 
-  /* The required object is not in the global scope, look to see if it is
-     a dependency of the current object.  */
-  for (n = 0; n < map->l_searchlist.r_nlist; n++)
-    if (_dl_name_match_p (name, map->l_searchlist.r_list[n]))
-      return map->l_searchlist.r_list[n];
-
-  /* Should never happen.  */
-  return NULL;
+  struct dl_exception exception;
+  _dl_exception_create_format
+    (&exception, DSO_FILENAME (map->l_name),
+     "missing soname %s in version dependency", name);
+  _dl_signal_exception (0, &exception, NULL);
 }
 
 
@@ -199,10 +195,6 @@  _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
 	  ElfW(Vernaux) *aux;
 	  struct link_map *needed = find_needed (strtab + ent->vn_file, map);
 
-	  /* If NEEDED is NULL this means a dependency was not found
-	     and no stub entry was created.  This should never happen.  */
-	  assert (needed != NULL);
-
 	  /* Make sure this is no stub we created because of a missing
 	     dependency.  */
 	  if (__builtin_expect (! trace_mode, 1)