Skip to content

Resolve dlsym(..., "errno") to the calling thread's errno - #20

Open
buyemune-sys wants to merge 2 commits into
pg83:mainfrom
buyemune-sys:fix/dlsym-errno
Open

buyemune-sys wants to merge 2 commits into
pg83:mainfrom
buyemune-sys:fix/dlsym-errno

Conversation

@buyemune-sys

Copy link
Copy Markdown

The problem

glibc's libc exports errno itself, a TLS object, and dlsym resolves it to the calling thread's instance. Compiled code goes through __errno_location, but foreign function interfaces reach the variable by name. LuaJIT's lib/ffi/redir.lua declares int redir_bar asm("errno") and writes to it through ffi.C. musl has no such symbol, so under the bridge the lookup failed:

$ ./dlsym_errno               # glibc
dlsym(errno)=found same_as_errno_location=1
$ solo ./dlsym_errno
dlsym(errno)=NULL same_as_errno_location=0

The fix

When nothing else defines the name, dlsym falls back to musl's errno of the calling thread (lib/glibc_shim.cpp:4727).

Test

The conformance battery checks that dlsym(RTLD_DEFAULT, "errno") == &errno.

On main the check fails. With the fix: ./build test passes.

buyemune-sys and others added 2 commits October 20, 2026 15:42
Security updates replaced libapparmor1 4.0.1really4.0.1-0ubuntu0.24.04.7
with .9 and libexpat1 2.6.1-2ubuntu0.4 with ubuntu0.6, and the pool kept
only the new files, so the cold-cache Fetch x86_64 job answers 404 and
every x86-64 job behind it is skipped. Both pins move to the versions
noble-updates ships now; their SHA256s match the archive's Packages index.
The other twelve pins are still served.
glibc's libc exports errno itself, a TLS object, and dlsym resolves it to
the calling thread's instance. Compiled code goes through
__errno_location, but foreign function interfaces reach the variable by
name: LuaJIT's lib/ffi/redir.lua test declares `int redir_bar
asm("errno")` and writes to it through ffi.C. musl has no such symbol, so
under the bridge the lookup failed with "symbol not found".

dlsym now falls back to musl's errno of the calling thread when nothing
else defines the name.

The conformance battery checks that dlsym(RTLD_DEFAULT, "errno") is
&errno.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant