Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Fri, 9 Feb 2018 18:07:25 +0000
From: Nicholas Wilson <nicholas.wilson@...lvnc.com>
To: "musl@...ts.openwall.com" <musl@...ts.openwall.com>
Subject: TLS storage offsets for TLS_ABOVE_TP

Hi,

I have a question about the support for TLS_ABOVE_TP ("TLS variant I").

In archs like ARM, we have a matched pair of functions TP_ADJ and __pthread_self, which adjust a pthread* to the thread-register and back again. For ARM, there's an additional offset of 8 (and 16 for AArch64), which is part of the ABI to ensure a) the TP points to the DTV, and b) the main module's TLS block is at a known offset from the TP.

However, the ARM adjustment code uses "TP = pthread* + sizeof(pthread) - 8". That's correct for the arch ABI, in that the linker requires that the thread storage be located 8 bytes above the TP, and Musl does indeed store the TLS block there right after the struct pthread.

But what's odd is that you have the pthread->dtv_copy member right at the end of the pthread struct. So the thread pointer is pointing not to pthread->dtv_copy, but actually to pthread->canary_at_end.

Is my mental compiler going wrong? I don't have an ARM machine to actually execute the code on, but I've just been staring at it for an hour and can't work it out.

One thing I have noticed is that in all the four TLS models (general dynamic, local dynamic, initial exec, local exec), the DTV isn't actually dereferenced directly by compiler-generated code. The whole thing about having the DTV available to the compiler in a known location in fact is not used! So maybe that's how you get away with.

For the sake of "correctness" and conformance though, I wonder if there should be a final "void *dtv_pad" member at the end of struct pthread, so that the DTV block at the end of the struct pthread has the right size for the platform.

I'd be happy to hear I'm wrong! (Maybe a diagram in the source code would help comprehension, to show how the memory is laid out, including the alignment bits and pieces. The FreeBSD libc source code has a helpful bit of ASCII art that draws the layout of the various bits of data and the alignment blocks between them.)

All the best,
Nick

Powered by blists - more mailing lists

Your e-mail address:

Powered by Openwall GNU/*/Linux - Powered by OpenVZ