public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jeff Law <law@redhat.com>
To: Wilco Dijkstra <Wilco.Dijkstra@arm.com>,
	Richard Earnshaw <Richard.Earnshaw@arm.com>,
	GCC Patches <gcc-patches@gcc.gnu.org>
Cc: nd <nd@arm.com>
Subject: Re: RFC: stack/heap collision vulnerability and mitigation with GCC
Date: Thu, 22 Jun 2017 16:10:00 -0000	[thread overview]
Message-ID: <65e55d54-caf5-ca5f-7835-7541091e7528@redhat.com> (raw)
In-Reply-To: <AM5PR0802MB26103E3BB141E670F3AED80183DA0@AM5PR0802MB2610.eurprd08.prod.outlook.com>

On 06/21/2017 11:47 AM, Wilco Dijkstra wrote:
> Jeff Law wrote:
> 
>> I'm a little confused.  I'm not defining or changing the ABI.  I'm
>> working within my understanding of the existing aarch64 ABI used on
>> linux systems.  My understanding after reading that ABI and the prologue
>> code for aarch64 is there's nothing that can currently be relied upon in
>> terms of the offset from the incoming stack pointer to the most recent
>> "probe" in the caller.
> 
> Well what we need is a properly defined ABI on when to emit probes.  That
> doesn't exist yet indeed, so there is nothing you can rely on today.  But that
> is true for any architecture. In particular if the caller hasn't been compiled with
> probes, even if the call instruction does an implicit probe, you still have to 
> assume that the stack guard has been breached already (ie. doing probes in
> the callee is useless if they aren't done in the whole call chain).
You can be in one of 3 states when you start the callee's prologue.

1. You're somewhere in the normal stack.

2. You've past the guard and are already in the heap or elsewhere

3. You're somewhere in the guard


State #1 is trivially handled.  You emit probes every PROBE_INTERVAL
bytes in newly allocated space and you're OK.

State #2 we can't do anything about.

State #3 is what we're trying to address.  The attacker has advanced the
stack pointer into the guard, but has not fully breached the guard.  We
need to ensure that we hit the guard to prevent the breach.

On x86 and ppc state #3 does not occur due to the ISA and ABI.  We rely
on not being in state #3 to avoid a great number of the explicit probes.

But on aarch64, s390 and likely many other architectures, state #3 is a
real possibility and we need to account for it.

As it stands right now we can be in state #3 and the stack pointer could
be STACK_BOUNDARY / BITS_PER_UNIT bytes away from the end of the guard.
If we were to emit a

stp lr, fp, [sp, -32]!

That would complete jumping the guard since it allocates 32 bytes of
space, then writes 16 and thus we do not hit the guard.


If (for example) the ABI were to mandate touching last outgoing arg slot
if it were > 1k and touch the last slot of the dynamic space in the
caller, then we would know that the stack pointer must be at least
3kbytes away from the end of the guard.  And thus

stp lr, fp, [sp, -32]!

Would hit the guard.  In fact, we could allocate up to 3kbytes of space
without a probe.

> Remember Richard's reply was to this:
>>> aarch64 is significantly worse.  There are no implicit probes we can
>>> exploit.  Furthermore, the prologue may allocate stack space 3-4 times.
>>> So we have the track the distance to the most recent probe and when that
>>> distance grows too large, we have to emit a probe.  Of course we have to
>>> make worst case assumptions at function entry.
> 
> As pointed out, AArch64 is not significantly worse since the majority of frames
> do not need any probes (let alone multiple probes as suggested), neither do we
> need to make worst-case assumptions on entry (stack guard has already been
> breached).
See above.  It is significantly worse on aarch64/s390 because we need to
account for case #3 above.  Whereas x86 and ppc do not because of how
their ISA and ABIs work.

> 
>> Just limiting the size of the outgoing arguments is not sufficient
>> though.  You still have the dynamic allocation area in the caller.  The
>> threat model assumes the caller follows the ABI, but does not have to
>> have been compiled with -fstack-check.
> 
> The only mitigation for that is to increase the stack guard. A callee cannot 
> somehow undo crossing the stack guard by an unchecked caller (that includes
> the case where calls do an implicit probe).
I think you're looking at case #2 above and indeed we can't do anything
about that.  If they've fully breached the guard, then there's nothing
we can do.  But if they have only partially breached the guard then we
can and should stop them (case #3).

jeff

  reply	other threads:[~2017-06-22 16:10 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-20 23:22 Wilco Dijkstra
2017-06-21  8:34 ` Richard Earnshaw (lists)
2017-06-21  8:44   ` Andreas Schwab
2017-06-21  8:46     ` Richard Earnshaw (lists)
2017-06-21  8:46       ` Richard Earnshaw (lists)
2017-06-21  9:03   ` Wilco Dijkstra
2017-06-21 17:05 ` Jeff Law
2017-06-21 17:47   ` Wilco Dijkstra
2017-06-22 16:10     ` Jeff Law [this message]
2017-06-22 22:57       ` Wilco Dijkstra
  -- strict thread matches above, loose matches on Subject: below --
2017-06-19 17:07 Jeff Law
2017-06-19 17:29 ` Jakub Jelinek
2017-06-19 17:45   ` Jeff Law
2017-06-19 17:51     ` Jakub Jelinek
2017-06-19 21:51       ` Jeff Law
2017-06-20  8:03       ` Uros Bizjak
2017-06-20 10:18         ` Richard Biener
2017-06-20 11:10           ` Uros Bizjak
2017-06-20 12:13             ` Florian Weimer
2017-06-20 12:17               ` Uros Bizjak
2017-06-20 12:20                 ` Uros Bizjak
2017-06-20 12:27                   ` Richard Biener
2017-06-20 21:57                     ` Jeff Law
2017-06-20 15:59                 ` Jeff Law
2017-06-19 18:00   ` Richard Biener
2017-06-19 18:02     ` Richard Biener
2017-06-19 18:15       ` Florian Weimer
2017-06-19 21:57         ` Jeff Law
2017-06-19 22:08       ` Jeff Law
2017-06-20  7:50   ` Eric Botcazou
2017-06-19 17:51 ` Joseph Myers
2017-06-19 17:55   ` Jakub Jelinek
2017-06-19 18:21   ` Florian Weimer
2017-06-19 21:56     ` Joseph Myers
2017-06-19 22:05       ` Jeff Law
2017-06-19 22:10         ` Florian Weimer
2017-06-19 19:05   ` Jeff Law
2017-06-19 19:45     ` Jakub Jelinek
2017-06-19 21:41       ` Jeff Law
2017-06-20  8:27     ` Richard Earnshaw (lists)
2017-06-20 15:50       ` Jeff Law
2017-06-19 18:12 ` Richard Kenner
2017-06-19 22:05   ` Jeff Law
2017-06-19 22:07     ` Richard Kenner
2017-06-20  8:21   ` Eric Botcazou
2017-06-20 15:50     ` Jeff Law
2017-06-20 19:48     ` Jakub Jelinek
2017-06-20 20:37       ` Eric Botcazou
2017-06-20 20:46         ` Jeff Law
2017-06-20  8:17 ` Eric Botcazou
2017-06-20 21:52   ` Jeff Law
2017-06-20 22:20     ` Eric Botcazou
2017-06-21 17:31       ` Jeff Law
2017-06-21 19:07     ` Florian Weimer
2017-06-21  7:56   ` Andreas Schwab
2017-06-20  9:27 ` Richard Earnshaw (lists)
2017-06-20 21:39   ` Jeff Law
2017-06-21  8:41     ` Richard Earnshaw (lists)
2017-06-21 17:25       ` Jeff Law
2017-06-22  9:53         ` Richard Earnshaw (lists)
2017-06-22 15:30           ` Jeff Law
2017-06-22 16:07             ` Szabolcs Nagy
2017-06-22 16:15               ` Jeff Law
2017-06-28  6:45           ` Florian Weimer
2017-07-13 23:21             ` Jeff Law
2017-07-18 19:54               ` Florian Weimer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=65e55d54-caf5-ca5f-7835-7541091e7528@redhat.com \
    --to=law@redhat.com \
    --cc=Richard.Earnshaw@arm.com \
    --cc=Wilco.Dijkstra@arm.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=nd@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).