NetBSD Problem Report #59567
From www@netbsd.org Thu Jul 31 13:39:09 2025
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature RSA-PSS (2048 bits) client-digest SHA256)
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id B785C1A923C
for <gnats-bugs@gnats.NetBSD.org>; Thu, 31 Jul 2025 13:39:09 +0000 (UTC)
Message-Id: <20250731133908.7914C1A923E@mollari.NetBSD.org>
Date: Thu, 31 Jul 2025 13:39:08 +0000 (UTC)
From: sagawa.aki+nbsd@gmail.com
Reply-To: sagawa.aki+nbsd@gmail.com
To: gnats-bugs@NetBSD.org
Subject: dladdr(3) doesn't work properly especially when main executable is loaded at high memory address
X-Send-Pr-Version: www-1.0
>Number: 59567
>Category: lib
>Synopsis: dladdr(3) doesn't work properly especially when main executable is loaded at high memory address
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: lib-bug-people
>State: analyzed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Jul 31 13:40:01 +0000 2025
>Closed-Date:
>Last-Modified: Sun Aug 03 19:58:28 +0000 2025
>Originator: Akihiro Sagawa
>Release: NetBSD 10.1
>Organization:
>Environment:
NetBSD xiaolan.local 10.1 NetBSD 10.1 (GENERIC) #0: Mon Dec 16 13:08:11 UTC 2024 mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/i386/compile/GENERIC i386
>Description:
I'm trying to run Wine on NetBSD/i386. When using ALSA lib (alisa-lib
and alsa-plugins-oss) to play a wav audio file, wine complains with the
following message and no sound is output.
> ALSA lib conf.c:4029:(snd_config_hooks_call) Cannot open shared library (null) (mmap of executable at correct address failed)
> ALSA lib conf.c:4658:(snd_config_update_r) hooks failed, removing configuration
Upon investigating the issue, I found that dladdr(3) appears to be the
source of the problem.
My Investigation:
_rtld_obj_from_addr function, called from dladdr(3), traverses
_rtld_objlist and returns the Obj_Entry object which satisfies
mapbase < addr < (mapbase + mapsize). However, the main executable's
mapsize is currently broken and has too large value. Thus, its result is
the main executable object. As a result, given addr is incorrectly
interpreted as belonging to the main executable rather than another shared library.
>How-To-Repeat:
As the compilation procedure for Wine is highly involved, a simplified
example is presented below.
[demo.c]----------------------------------------------------------------
#include <stdio.h>
#include <dlfcn.h>
int main(int argc, char* argv[])
{
Dl_info dlinfo;
int ret;
ret = dladdr(printf, &dlinfo);
printf("ret=%d, name=%s\n", ret, dlinfo.dli_fname);
return 0;
}
------------------------------------------------------------------------
To compile the file, run:
% gcc -fno-plt -g -O -Wl,-Ttext-segment=0x78000000 -o demo demo.c
Expected Result:
% $PWD/demo
ret=1, name=/usr/lib/libc.so.12
Actual Result:
% $PWD/demo
ret=1, name=/home/sagawa/dladdr/demo
Debug procedure:
% gdb ./demo
(gdb) b dladdr
Function "dladdr" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (dladdr) pending.
(gdb) run
Starting program: /home/sagawa/dladdr/demo
Breakpoint 1, dladdr (addr=0xb138a557 <printf>, info=0xbfb4753c)
at /usr/src/libexec/ld.elf_so/rtld.c:1339
1339 {
(gdb) info proc mappings
process 7029
Mapped address spaces:
Start Addr End Addr Size Offset Flags File
0x78000000 0x78001000 0x1000 0x0 r-x C-PD /home/sagawa/dladdr/demo
0x78001000 0x78002000 0x1000 0x0 rw- C-PD
(*snip*)
(gdb) p/x _rtld_objlist->mapsize
$1 = 0x78001000
mapsize should be 0x1000 at this point as shown in gdb's "info proc mapping" Size column.
>Fix:
Here is the proposed patch for NetBSD-current which fixes the main executable's mapsize in _rtld_objlist.
Otherwise, the value of obj->vaddrbase is zero when the line "size =
roundup(vaddr + ph->p_memsz) - obj->vaddrbase;" is executed at the first time.
Index: ld.elf_so/headers.c
===================================================================
RCS file: /cvsroot/src/libexec/ld.elf_so/headers.c,v
retrieving revision 1.75
diff -u -r1.75 headers.c
--- ld.elf_so/headers.c 2 May 2025 23:03:16 -0000 1.75
+++ ld.elf_so/headers.c 31 Jul 2025 12:33:07 -0000
@@ -551,14 +551,15 @@
break;
case PT_LOAD:
- size = round_up(vaddr + ph->p_memsz) - obj->vaddrbase;
if (first_seg) { /* First load segment */
obj->vaddrbase = round_down(vaddr);
obj->mapbase = (caddr_t)(uintptr_t)obj->vaddrbase;
+ size = round_up(vaddr + ph->p_memsz) - obj->vaddrbase;
obj->textsize = size;
obj->mapsize = size;
first_seg = false;
} else { /* Last load segment */
+ size = round_up(vaddr + ph->p_memsz) - obj->vaddrbase;
obj->mapsize = MAX(obj->mapsize, size);
}
dbg(("headers: %s %p phsize %" PRImemsz,
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->analyzed
State-Changed-By: riastradh@NetBSD.org
State-Changed-When: Sun, 03 Aug 2025 19:58:28 +0000
State-Changed-Why:
Problem has been analyzed. Patch has been provided.
Need:
[ ] automatic test to exercise the bug
[ ] pullup-9, [ ] pullup-10, [ ] pullup-11
We appear to have absolutely no direct tests of dladdr(3). Closest
we have is tests of libexecinfo's backtrace_symbols_fmt, which calls
dladdr(3), in tests/lib/libexecinfo. We could add a variant
libexecinfo test with -fno-plt -Ttext-segment=<high> to trigger this,
but we should also have some direct tests of dladdr(3).
Rather than relying on -fno-plt -Ttext-segment=<high> and using
dladdr's search as a proxy, I wonder if obj->mapsize or obj->textsize
is exposed more directly anywhere else like dlinfo(3) RTLD_DI_LINKMAP
which we could compare to the PT_LOAD segment obtained by
dl_iterate_phdr(3).
(Writing down all the analogous linker arguments for each
architecture, and verifying they exercise the bug, sounds like a
pain!)
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2025
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.