diff mbox series

[uclibc-ng-devel] avoid crashes in statical linked binaries when dlopen()

Message ID 384972885.3241.1760792040229@communicator.strato.de
State New
Headers show
Series [uclibc-ng-devel] avoid crashes in statical linked binaries when dlopen() | expand

Commit Message

tinyusbboard .matrixstorm Oct. 18, 2025, 12:54 p.m. UTC
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>
---
 ldso/ldso/dl-elf.c | 44 ++++++++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 20 deletions(-)

Comments

Waldemar Brodkorb Oct. 18, 2025, 5:27 p.m. UTC | #1
Hi,

thanks for the patch. Works now as expected.
commited and pushed,
 best regards
  Waldemar

tinyusbboard .matrixstorm wrote,

> 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>
> ---
>  ldso/ldso/dl-elf.c | 44 ++++++++++++++++++++++++--------------------
>  1 file changed, 24 insertions(+), 20 deletions(-)
> 
> diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
> index 6656acb0f..dc2185d7d 100644
> --- a/ldso/ldso/dl-elf.c
> +++ b/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
>  
>  
> -- 
> 2.30.2
> _______________________________________________
> devel mailing list -- devel@uclibc-ng.org
> To unsubscribe send an email to devel-leave@uclibc-ng.org
>
diff mbox series

Patch

diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 6656acb0f..dc2185d7d 100644
--- a/ldso/ldso/dl-elf.c
+++ b/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