This is the mail archive of the
mailing list for the glibc project.
Re: [RFC] nptl: change default stack guard size of threads
- From: Wilco Dijkstra <Wilco dot Dijkstra at arm dot com>
- To: Florian Weimer <fweimer at redhat dot com>, Szabolcs Nagy <Szabolcs dot Nagy at arm dot com>, GNU C Library <libc-alpha at sourceware dot org>
- Cc: nd <nd at arm dot com>, Jeff Law <law at redhat dot com>, Richard Earnshaw <Richard dot Earnshaw at arm dot com>, Rich Felker <dalias at libc dot org>, James Greenhalgh <James dot Greenhalgh at arm dot com>
- Date: Wed, 6 Dec 2017 14:27:00 +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=Wilco dot Dijkstra at arm dot com;
- Nodisclaimer: True
- References: <5A1ECB40.firstname.lastname@example.org> <email@example.com> <5A1EFF28.firstname.lastname@example.org> <email@example.com> <HE1PR0801MB205834BDB77C2208C953FD2E833B0@HE1PR0801MB2058.eurprd08.prod.outlook.com>,<firstname.lastname@example.org>
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:99
Florian Weimer wrote:
> On 11/29/2017 11:28 PM, Wilco Dijkstra wrote:
>> It's not related to what GLIBC needs, but GLIBC, like Linux, must continue to
>> run old binaries so a larger guard size is definitely beneficial. No existing code
>> uses probing, so increasing the guard size means far fewer functions could
>> jump the guard. The dropoff is exponential, each doubling of guard page size
>> halves the number of functions with a stack larger than the guard size.
> That's not actually true in the sense that the math doesn't work out
> that way. If you have a weird function which skips by a really large
> amount, you can double the guard size many, many times until the number
> of unprotected functions drops further.
> And there is definitely a long tail here, due to GNU's affinity to
> variable-length arrays and alloca.
The math works fine for most of the curve. The measurements I did
show that the number of functions with really large stack allocations is
extremely small. So it's a long tail only in terms of maximum stack
allocation, not in number of functions.
> So far, I haven't seen a strong argument that 64 KiB is better than 32
> KiB, or that switching to 96 KiB or 128 KiB would not provide additional
> protection. To me, it's still an arbitrary number.
It's based on actual measurements. Increasing the guard further will indeed
improve protection slightly. However the returns are diminishing once you
hit the tail of the curve. The first few doublings matter the most (in that sense
it's similar to ASLR). In principle using a 1MB thread stack guard would be
slightly better but I think that eats too much address space even on a 64-bit
system, so it doesn't feel like a good tradeoff.
> Based on the ld.so experience, I think it is questionable that existing
> vulnerable applications can be fixed by increasing the guard size. Our
> expectation is that we have to recompile with -fstack-clash-protection
> to get deterministic crashes (which we are doing with glibc), or to
> patch them to avoid the stack jump (which we did for ld.so because the
> GCC support wasn't available at the time).
It was very clear from the start that no guard size can "fix" all existing
applications. Increasing the guard just makes it much harder to find
functions that can jump the guard as there are so few of them. That's
the best we can do for existing binaries.
To get to a safer state, probing must be enabled by default everywhere,
but that also means probing should have a low overhead.