Improve handling of dlopen(RTLD_TRACE) aka ldd, of a library that
authorguenther <guenther@openbsd.org>
Tue, 15 Aug 2023 06:26:34 +0000 (06:26 +0000)
committerguenther <guenther@openbsd.org>
Tue, 15 Aug 2023 06:26:34 +0000 (06:26 +0000)
is already loaded:
 * add a 'trace' argument to _dl_show_objects() and exit the
   walk-the-objects loop if you hit that traced object
 * in dlopen(), pass the trace object to _dl_show_objects()
 * also, invoke _dl_show_objects() + exit if the object was
   already opened
 * pass NULL to _dl_show_objects() for all the other calls
 * oh hey, _dl_tracelib is now superfluous: _dl_show_objects()
   should do the walk-the-objects loop only if trace is not NULL.

Problem noted by gnezdo@
ok millert@

libexec/ld.so/dlfcn.c
libexec/ld.so/loader.c
libexec/ld.so/resolve.h
libexec/ld.so/util.h

index 3b3dbdb..2aee958 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dlfcn.c,v 1.114 2023/07/08 14:09:43 jasper Exp $ */
+/*     $OpenBSD: dlfcn.c,v 1.115 2023/08/15 06:26:34 guenther Exp $ */
 
 /*
  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -39,7 +39,6 @@
 #include "archdep.h"
 
 int _dl_errno;
-static int _dl_tracelib;
 
 static int _dl_real_close(void *handle);
 static lock_cb *_dl_thread_fnc = NULL;
@@ -72,7 +71,6 @@ dlopen(const char *libname, int flags)
 
        if ((flags & RTLD_TRACE) == RTLD_TRACE) {
                _dl_traceld = 1;
-               _dl_tracelib = 1;
        }
 
        DL_DEB(("dlopen: loading: %s\n", libname));
@@ -110,6 +108,11 @@ dlopen(const char *libname, int flags)
                /* if opened but grpsym_vec has not been filled in */
                if (object->grpsym_vec.len == 0)
                        _dl_cache_grpsym_list_setup(object);
+               if (_dl_traceld) {
+                       _dl_show_objects(object);
+                       _dl_unload_shlib(object);
+                       _dl_exit(0);
+               }
                goto loaded;
        }
 
@@ -126,7 +129,7 @@ dlopen(const char *libname, int flags)
                int err;
                DL_DEB(("tail %s\n", object->load_name ));
                if (_dl_traceld) {
-                       _dl_show_objects();
+                       _dl_show_objects(object);
                        _dl_unload_shlib(object);
                        _dl_exit(0);
                }
@@ -250,7 +253,7 @@ dlctl(void *handle, int command, void *data)
                break;
        }
        case 0x20:
-               _dl_show_objects();
+               _dl_show_objects(NULL);
                retval = 0;
                break;
        case 0x21:
@@ -486,7 +489,7 @@ _dl_tracefmt(int fd, elf_object_t *object, const char *fmt1, const char *fmt2,
 }
 
 void
-_dl_show_objects(void)
+_dl_show_objects(elf_object_t *trace)
 {
        elf_object_t *object;
        char *objtypename;
@@ -514,12 +517,15 @@ _dl_show_objects(void)
                _dl_dprintf(outputfd, "\tStart   %s End     %s Type  Open Ref GrpRef Name\n",
                    pad, pad);
 
-       if (_dl_tracelib) {
-               for (; object != NULL; object = object->next)
+       if (trace != NULL) {
+               for (; object != NULL; object = object->next) {
+                       if (object == trace)
+                               break;
                        if (object->obj_type == OBJTYPE_LDR) {
                                object = object->next;
                                break;
                        }
+               }
        }
 
        for (; object != NULL; object = object->next) {
index 7a32013..52e7b03 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: loader.c,v 1.213 2023/07/08 14:09:43 jasper Exp $ */
+/*     $OpenBSD: loader.c,v 1.214 2023/08/15 06:26:34 guenther Exp $ */
 
 /*
  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -701,7 +701,7 @@ _dl_boot(const char **argv, char **envp, const long dyn_loff, long *dl_data)
        if (_dl_debug || _dl_traceld) {
                if (_dl_traceld)
                        _dl_pledge("stdio rpath", NULL);
-               _dl_show_objects();
+               _dl_show_objects(NULL);
        }
 
        DL_DEB(("dynamic loading done, %s.\n",
index 19e8bea..d32279d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: resolve.h,v 1.104 2023/01/29 20:30:56 gnezdo Exp $ */
+/*     $OpenBSD: resolve.h,v 1.105 2023/08/15 06:26:34 guenther Exp $ */
 
 /*
  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -347,6 +347,9 @@ void        _dl_trace_setup(char **) __boot;
 void   _dl_trace_object_setup(elf_object_t *);
 int    _dl_trace_plt(const elf_object_t *, const char *);
 
+/* dlfcn.c */
+void   _dl_show_objects(elf_object_t *_object);
+
 /* tib.c */
 void   _dl_allocate_tls_offsets(void) __boot;
 void   _dl_allocate_first_tib(void) __boot;
index d2f47ba..6a91472 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: util.h,v 1.38 2023/01/29 20:30:21 gnezdo Exp $        */
+/*     $OpenBSD: util.h,v 1.39 2023/08/15 06:26:34 guenther Exp $      */
 
 /*
  * Copyright (c) 1998 Todd C. Miller <millert@openbsd.org>
@@ -59,7 +59,6 @@ size_t _dl_strlcat(char *dst, const char *src, size_t siz);
 void _dl_printf(const char *fmt, ...);
 void _dl_vprintf(const char *fmt, va_list ap);
 void _dl_dprintf(int, const char *fmt, ...);
-void _dl_show_objects(void);
 void _dl_arc4randombuf(void *, size_t);
 u_int32_t _dl_arc4random(void);
 ssize_t _dl_write(int fd, const char* buf, size_t len);