Browse Source

avoid crashes in statical linked binaries when dlopen()

Even in current (1.0.55) releaes of uClibc-ng there will be 100% reproducible crashes of statically linked binaries (on all kind of platforms), when calling "dlopen(...)" with wrong or non-existing .so-files).

#0  0x0000000000404b62 in _dl_load_shared_library ()
#1  0x0000000000404d49 in do_dlopen ()
#2  0x0000000000405286 in dlopen ()

This is caused by missing checks on "_dl_loaded_modules" in "ldso/ldso/dl-elf.c".
When "_dl_loaded_modules" is NULL in static linked binaries, it becomes dereferenced and causes an segfault.

This patch fixes the issue by adding an extra assignment-check for "_dl_loaded_modules".

Signed-off-by: Stephan Baerwolf <stephan@matrixstorm.com>
tinyusbboard .matrixstorm 3 months ago
parent
commit
3dcc84c74e
1 changed files with 24 additions and 20 deletions
  1. 24 20
      ldso/ldso/dl-elf.c

+ 24 - 20
ldso/ldso/dl-elf.c

@@ -276,12 +276,14 @@ struct elf_resolve *_dl_load_shared_library(unsigned int rflags, struct dyn_elf
         /*
          * Try the DT_RPATH of the executable itself.
          */
-        pnt = (char *) _dl_loaded_modules->dynamic_info[DT_RPATH];
-        if (pnt) {
-                pnt += (unsigned long) _dl_loaded_modules->dynamic_info[DT_STRTAB];
-                _dl_if_debug_dprint("\tsearching exe's RPATH='%s'\n", pnt);
-                if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt, NULL)) != NULL)
-                        return tpnt1;
+        if (_dl_loaded_modules) {
+            pnt = (char *) _dl_loaded_modules->dynamic_info[DT_RPATH];
+            if (pnt) {
+                    pnt += (unsigned long) _dl_loaded_modules->dynamic_info[DT_STRTAB];
+                    _dl_if_debug_dprint("\tsearching exe's RPATH='%s'\n", pnt);
+                    if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt, NULL)) != NULL)
+                            return tpnt1;
+            }
         }
 #endif
 #endif
@@ -361,20 +363,22 @@ struct elf_resolve *_dl_load_shared_library(unsigned int rflags, struct dyn_elf
 	 * abusing this bug^Wrelaxed, user-friendly behaviour.
 	 */
 
-	pnt = (char *) _dl_loaded_modules->dynamic_info[DT_RUNPATH];
-	if (pnt) {
-		pnt += (unsigned long) _dl_loaded_modules->dynamic_info[DT_STRTAB];
-		_dl_if_debug_dprint("\tsearching exe's RUNPATH='%s'\n", pnt);
-		if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt, NULL)) != NULL)
-			return tpnt1;
-	}
-	pnt = (char *) _dl_loaded_modules->dynamic_info[DT_RPATH];
-	if (pnt) {
-		pnt += (unsigned long) _dl_loaded_modules->dynamic_info[DT_STRTAB];
-		_dl_if_debug_dprint("\tsearching exe's RPATH='%s'\n", pnt);
-		if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt, NULL)) != NULL)
-			return tpnt1;
-	}
+    if (_dl_loaded_modules) {
+        pnt = (char *) _dl_loaded_modules->dynamic_info[DT_RUNPATH];
+        if (pnt) {
+            pnt += (unsigned long) _dl_loaded_modules->dynamic_info[DT_STRTAB];
+            _dl_if_debug_dprint("\tsearching exe's RUNPATH='%s'\n", pnt);
+            if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt, NULL)) != NULL)
+                return tpnt1;
+        }
+        pnt = (char *) _dl_loaded_modules->dynamic_info[DT_RPATH];
+        if (pnt) {
+            pnt += (unsigned long) _dl_loaded_modules->dynamic_info[DT_STRTAB];
+            _dl_if_debug_dprint("\tsearching exe's RPATH='%s'\n", pnt);
+            if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt, NULL)) != NULL)
+                return tpnt1;
+        }
+    }
 #endif