This is the mail archive of the
mailing list for the glibc project.
Re: [RFC] nptl: change default stack guard size of threads
- From: Szabolcs Nagy <szabolcs dot nagy at arm dot com>
- To: Rich Felker <dalias at libc dot org>
- Cc: nd at arm dot com, Jeff Law <law at redhat dot com>, James Greenhalgh <james dot greenhalgh at arm dot com>, Florian Weimer <fweimer at redhat dot com>, GNU C Library <libc-alpha at sourceware dot org>, Richard Earnshaw <Richard dot Earnshaw at arm dot com>, Wilco Dijkstra <Wilco dot Dijkstra at arm dot com>
- Date: Tue, 12 Dec 2017 18:07:13 +0000
- Subject: Re: [RFC] nptl: change default stack guard size of threads
- Authentication-results: sourceware.org; auth=none
- Authentication-results: spf=none (sender IP is ) smtp.mailfrom=Szabolcs dot Nagy at arm dot com;
- Nodisclaimer: True
- References: <5A1ECB40.email@example.com> <firstname.lastname@example.org> <5A1EFF28.email@example.com> <firstname.lastname@example.org> <20171129205148.GG1627@brightrain.aerifal.cx> <email@example.com> <20171205105530.GA12966@arm.com> <firstname.lastname@example.org> <5A2FC0BB.email@example.com> <20171212163649.GC1627@brightrain.aerifal.cx>
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:99
On 12/12/17 16:36, Rich Felker wrote:
> On Tue, Dec 12, 2017 at 11:42:51AM +0000, Szabolcs Nagy wrote:
>> On 11/12/17 23:49, Jeff Law wrote:
>>> On 12/05/2017 03:55 AM, James Greenhalgh wrote:
>>>>>> GCC needs to emit probe intervals for the smallest supported page size
>>>>>> on the the target architecture. If it does not do that, we end up in
>>>>>> trouble on the glibc side.
>>>> This is where I may have a misunderstanding, why would it require probing
>>>> at the smallest page size, rather than probing at a multiple of the guard
>>>> size? It is very likely I'm missing something here as I don't know the glibc
>>>> side of this at all.
>>> I'm not sure where that statement comes from either. I guess the
>>> concern is someone could boot a kernel with a smaller page size and
>>> perhaps the kernel/glibc create their guards based on # pages rather
>>> than absolute size. Thus booting a kernel with a smaller pagesize would
>>> code with less protection.
>> historically posix required a single page guard at the
>> end of thread stacks, that's what all existing libcs
>> implement and glibc internally assumes this at several
>> places where stack/guard size accounting happens.
>> (so larger guard is not conform to posix-2004, only
>> to >=posix-2008)
> I don't follow your reasoning about how a conformance distinction can
> be made here. There is no formal model for "does not have additional
> guard pages"; that's just an implementation detail of the memory
> layout. As a thought experiment, a hardened kernel might always put
> giant randomly-perturbed guard zones before and after every mmap.
> If the default size was actually specified to be one page in old POSIX
> and pthread_attr_getstacksize exposed a larger size for the default, I
> suppose this could be a conformance distinction, but I'm not aware of
> such a requirement.
pthread_attr_getguardsize must return the user setting or
the default value (which was required to be 1 page), glibc
has tests for this.
of course it can lie about the guardsize (internally use
large default guard size but only report 1 page)
>> users can also set the guard size explicitly when creating
>> threads (at least openjdk and erlang do this for threads
>> that call c code) and that's not something glibc can change:
>> it is allowed to round this up to pagesize but not to
>> some arbitrary larger value.
> Likewise I think this is mistaken, for the above reason. If the
> rounding-up happens at pthread_create time rather than when setting
> the attribute, it's certainly not observable as a conformance
> distinction. Of course it is a QoI distinction in both directions:
> - Rounding up reduces the available virtual memory space, possibly
> limiting the size of an application (detriment to QoI).
well glibc has non-standard apis (pthread_getattr_np) that
makes the guardsize of a thread visible (again this can lie)
if rounding up the guardsize to some large value actually break
existing setups then it is problematic even if there is no
i think such breakage is very unlikely (running into a limit
because of 64k guard would mean the code was extremely fragile
and would not work on a system with 64k page size).
otoh if the pthread_attr_get/setguardsize apis do not get/set
the actual guard size then these apis don't have much point
(i.e. users who "know what they are doing" and need to set
the guard size can't use them) so i'm not sure if doing something
different internally that is visible via these apis is what
users would want.
> - Rounding up may limit the impact of stack overflow bugs to a crash
> rather than something more severe (QoI advantage).
> There are also other safety improvements that could be made at the
> expense of virtual memory space and run time costs. For instance in
> musl I've considered a hardening option to put guard pages (maybe
> repeating the requested guard size? or just one page?) between the end
> of the stack and the TLS area so that stack-based overflows can't
> clobber TLS/TCB. But this is rather costly since it doubles the number
> of kernel VMAs needed, so I'm very hesitant to do it without evidence
> that it would thwart real-world vulns.
>> glibc has another problem that it does stack accounting
>> incorrectly and thus increasing the guard size can easily
>> make existing code fail with stack overflow and fixing
>> this is non-trivial since many users already expect the
>> buggy behaviour (with glibc specific workarounds)
> This indeed needs to be fixed, whatever is done with regards to
> default guard size.