- edited description
ldd(1) overrides ld.so(1)'s _rtld_pagesz, but it may causes SIGFPE in xmalloc().
first, _rtld_pagesz is used for ld.so(1)'s own malloc(so called imalloc).
http://nxr.netbsd.org/xref/src/libexec/ld.elf_so/xmalloc.c#188
175 static void *
176 imalloc(size_t nbytes)
177 {
...
187 if (pagesz == 0) {
188 pagesz = n = _rtld_pagesz;
189 if (morepages(NPOOLPAGES) == 0)
190 return NULL;
_rtld_pagesz may assigned certain value(>0) in _rtld().
http://nxr.netbsd.org/xref/src/libexec/ld.elf_so/rtld.c#519
402 Elf_Addr
403 _rtld(Elf_Addr *sp, Elf_Addr relocbase)
404 {
...
519 _rtld_pagesz = (int)pAUX_pagesz->a_v;
but ldd(1) may override this symbol.
http://nxr.netbsd.org/xref/src/usr.bin/ldd/ldd.c#103
103 size_t _rtld_pagesz;
and assign value(>0) taken from sysconf(3) in elf{32,64}_ldd().
http://nxr.netbsd.org/xref/src/usr.bin/ldd/ldd_elfxx.c#105
94 int
95 ELFNAME(ldd)(int fd, char *path, const char *fmt1, const char *fmt2)
96 {
...
105 _rtld_pagesz = sysconf(_SC_PAGESIZE);
so that if ld.so(1) load ldd(1)'s binary and don't call elf{32,64}_ldd() _rtld_pagesz is leaved as zero.
$ gdb --quiet /usr/bin/ldd
Reading symbols from /usr/bin/ldd...done.
(gdb) b usage
Breakpoint 1 at 0x401510: file /usr/src/usr.bin/ldd/build/../ldd.c, line 111.
(gdb) run
Starting program: /usr/bin/ldd
Breakpoint 1, usage () at /usr/src/usr.bin/ldd/build/../ldd.c:111
111 {
(gdb) print _rtld_pagesz
$1 = 0
(gdb)
so, if libc called ld.so(3)'s function that uses imalloc internally (eg: _rtld_tls_get_addr() for Thread Local Storage), imalloc's NPOOLPAGES macro may throws SIGFPE(division by zero exception).
http://nxr.netbsd.org/xref/src/libexec/ld.elf_so/xmalloc.c#98
98 #define NPOOLPAGES (32*1024/pagesz)
...
188 pagesz = n = _rtld_pagesz;
189 if (morepages(NPOOLPAGES) == 0)
Comments (4)
-
reporter -
reporter i believe NetBSD's ldd(1) implentation is evil. don't try to parse ELF binary itself. ld.so(1) should implement LD_TRACE_LOADED_OBJECT=1 trace function and ldd(1) must be ld.so(1)'s wrapper application.
-
reporter - changed status to resolved
BUGFIX: Issue
#86-- ldd(1) overrides ld.so(1)'s _rtld_pagesz, but it may causes SIGFPE in xmalloc().→ <<cset 27b39b6d4b4d>>
-
reporter this is kludge fix, again and again real fix is implement LD_TRACE_LOADED_OBJECT=1 trace function.
- Log in to comment