NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/58865: static and dynamic dl_iterate_phdr disagree on main object name



>Number:         58865
>Category:       lib
>Synopsis:       static and dynamic dl_iterate_phdr disagree on main object name
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Nov 30 03:35:00 +0000 2024
>Originator:     Taylor R Campbell
>Release:        current, 10, 9, ...
>Organization:
The AT_NETBSD_EXECFOUNDATION
>Environment:
>Description:
Static dl_iterate_phdr (lib/libc/dlfcn/dlfcn_elf.c) gives AT_SUN_EXECNAME as the main object's struct dl_phdr_info::dlpi_name:

    174 		case AT_SUN_EXECNAME:
    175 			dlpi_name = (void *)aux->a_v;
    176 			break;
...
    216 	phdr_info.dlpi_name = dlpi_name;
    217 
    218 	return callback(&phdr_info, sizeof(phdr_info), data);

https://nxr.netbsd.org/xref/src/lib/libc/dlfcn/dlfcn_elf.c?r=1.17#174

Dynamic dl_iterate_phdr (libexec/ld.elf_so/rtld.c) instead gives argv[0] as the main object's struct dl_phdr_info::dlpi_name:

    682 		_rtld_objmain->path = xstrdup(argv[0] ? argv[0] :
    683 		    "main program");
...
   1467 	/* XXX: wrong but not fixing it yet */
   1468 	phdr_info->dlpi_name = obj->path;

https://nxr.netbsd.org/xref/src/libexec/ld.elf_so/rtld.c?r=1.217#682

ld.elf_so does read out AT_SUN_EXECNAME, but only uses it for $ORIGIN.

Not a priori clear which one is correct but I lean toward AT_SUN_EXECNAME since there is otherwise no way to obtain it without going through the undocumented _dlauxinfo().
>How-To-Repeat:
$ pwd
/tmp/riastradh
$ cat dlx.c
#include <dlfcn.h>
#include <elf.h>
#include <errno.h>
#include <link.h>
#include <stdio.h>

static int
callback(struct dl_phdr_info *dlpi, size_t size, void *cookie)
{

	printf("dl_iterate_phdr name=%s\n", dlpi->dlpi_name);
	return 1;
}

int
main(void)
{
	const AuxInfo *aux;

	for (aux = _dlauxinfo(); aux->a_type != AT_NULL; aux++) {
		switch (aux->a_type) {
		case AT_SUN_EXECNAME:
			printf("AT_SUN_EXECNAME=%s\n", (char *)aux->a_v);
			break;
		}
	}

	dl_iterate_phdr(&callback, NULL);
	return 0;
}
$ rm -f dlx && make dlx DBG=-g\ -O2\ -Wall\ -Werror && ./dlx
cc -g -O2 -Wall -Werror   -o dlx dlx.c 
AT_SUN_EXECNAME=/tmp/riastradh/./dlx
dl_iterate_phdr name=./dlx
$ rm -f dlx && make dlx DBG=-g\ -O2\ -Wall\ -Werror\ -static && ./dlx
cc -g -O2 -Wall -Werror -static   -o dlx dlx.c 
AT_SUN_EXECNAME=/tmp/riastradh/./dlx
dl_iterate_phdr name=/tmp/riastradh/./dlx
>Fix:
Yes, please!



Home | Main Index | Thread Index | Old Index