Page MenuHomeFreeBSD

Revert "rtld: fix allocate_module_tls() variant I fallback to static allocation"
ClosedPublic

Authored by jrtc27 on May 28 2025, 1:21 AM.
Tags
None
Referenced Files
F132413260: D50565.id156207.diff
Thu, Oct 16, 5:42 PM
Unknown Object (File)
Tue, Oct 14, 3:44 AM
Unknown Object (File)
Sat, Oct 11, 3:25 AM
Unknown Object (File)
Thu, Oct 9, 9:24 PM
Unknown Object (File)
Wed, Oct 8, 3:34 AM
Unknown Object (File)
Sun, Oct 5, 9:22 PM
Unknown Object (File)
Fri, Oct 3, 9:23 PM
Unknown Object (File)
Fri, Oct 3, 5:10 PM
Subscribers

Details

Summary

This was applying a NetBSD fix to FreeBSD. However, the original code
was correct for FreeBSD. NetBSD's obj->tlsoffset is relative to the end
of the TCB, not the TCB itself, whilst ours is relative to the TCB
itself. For example, our allocate_tls uses (char *)tcb + obj->tlsoffset
for the memcpy and memset calls.

Without this reverted, for dynamically loaded shared objects, Initial
Exec accesses to TLS variables on variant I architectures (non-x86) use
the correct address, whilst General Dynamic and dlsym(3) use the
incorrect address (TLS_TCB_SIZE past the start). Note that, on arm64,
LLVM only supports TLSDESC (including LLD) and TLSDESC will use the
static resolver if the variable ends up allocated to the static TLS
block, even in the presence of dlopen(3), so only dlsym(3) shows the
discrepancy there.

Whilst here, add a comment to explain this difference to try and avoid
the same mistake being made in future.

[1] In the case of variant II, it's the amount to subtract, so still

positive

This reverts commit e9a38ed2fa61fd264a80f24ceb35f39b0ac6463d.

Fixes: e9a38ed2fa61 ("rtld: fix allocate_module_tls() variant I fallback to static allocation")
MFC after: 1 week

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

I've gone digging and this looks like confusion importing NetBSD's code. This was applying https://github.com/NetBSD/src/commit/cc08a85a2529815b95799c6500b40a2c596c0c93 to our tree, just as 91880e07f605edb90339685bc934699a4344de3b was https://github.com/NetBSD/src/commit/3caa8dc7351c8383b2c3832b2610624b347e9065. The key point is that FreeBSD's tlsoffset is always relative to the TCB, whereas for Variant I TLS on NetBSD it's relative to the end of the TCB. So the original code was wrong for NetBSD but right for FreeBSD, and the updated code fixed it for NetBSD but broke FreeBSD by importing it. Will update the commit message with a properly-written summary tomorrow.

This revision is now accepted and ready to land.May 28 2025, 4:05 PM

I would ask to add some explanation of difference between our and netbsd code directly to rtld.c. Smaller arches often get fixes from netbsd.

Extend existing comment to note different implementation to NetBSD

This revision now requires review to proceed.May 28 2025, 4:31 PM
This revision was not accepted when it landed; it landed in state Needs Review.May 28 2025, 8:29 PM
This revision was automatically updated to reflect the committed changes.