This is the mail archive of the
mailing list for the GCC project.
Re: RFC: stack/heap collision vulnerability and mitigation with GCC
On 06/19/2017 03:56 PM, Joseph Myers wrote:
> On Mon, 19 Jun 2017, Florian Weimer wrote:
>> I think architectures such as aarch64 without implied stack probing as
>> part of the function call sequence would benefit most from an ABI
>> agreement (splitting the probing responsibility in some way between
>> caller and callee). For architectures with some form of implied
> I'd expect that, regardless of architecture, if calls don't write to the
> stack, the caller has to save its own return address somewhere before
> making a call, which means writing the saved link register.
True, but the callee doesn't know the offset where the caller saved the
return address. In fact, different callers could have stored it at
different offsets. AFAICT for these targets we just have to make a
worst case assumption about the caller.
> problem case something like: the caller allocates stack space
> unconditionally, without writing to it, and then a particular case in the
> caller calls what it believes to be a noreturn function, or a function
> that it knows won't return in that particular case, so doesn't need to
> save the return address (although not saving return addresses when calling
> noreturn functions is problematic in practice when you want to backtrace
> from abort), so makes a call without ever having written anything to the
> stack (and then you chain many such calls to do large stack allocations,
> never writing to the stack, with each individual allocation being small)?
Noreturn functions are a bit special. In the interest of safety my
patches do two things.
1. Callee always probes *(sp+small offset). This avoids problems if the
caller allocated spaced, but turned the call into a jump because it knew
the callee was no-return and thus it didn't need to tear down the
caller's frame. GCC doesn't do this optimization anyway, but better
safe than sorry.
2. GCC will explicitly refuse to optimize a call to a noreturn function
into a jump.
> Or is the concern simply that the caller might have been compiled without
> stack checking and you don't know *where* it wrote to the stack, even
> given that it must have saved its return address somewhere?
Right. In a mixed environment, you don't know if the caller was
compiled with -fstack-check or not. So unless the architecture does
something useful (stores the return pointer on the stack) or ABI
mandates something useful (*sp always contains outer frame), then you
have to make worst case assumptions.