On Wed, 2020-08-05 at 18:12 +0100, Richard Sandiford wrote:
> PR96191 [https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96191]
> was a bug raised against the aarch64 implementation of -fstack-protector.
> As it happens, the same bug affected arm, but AFAICT those are the only
> two affected targets.
> 
> -fstack-protector works by:
> 
> * creating a special canary slot in the stack frame,
> * initialising it with a special canary value, and then
> * checking at the end of the function whether the canary slot still has
>   the correct value.
> 
> If the slot has changed value, the function calls a special stack-smash
> handler that would typically abort the program.
> 
> On many targets, the code that sets up and tests the canary slot will
> need to load the canary value into registers.  However, GCC tries
> to guarantee that this value does not remain in registers beyond the
> “test” and “set” operations.  For example, the documentation of the
> stack_protect_test pattern says:
> 
>   This pattern, if defined, compares a @code{ptr_mode} value from the
>   valid memory location in operand 1 with the memory in operand 0 without
>   leaving the value in a register afterward and branches to operand 2 if
>   the values were equal.
> 
>   If this pattern is not defined, then a plain compare pattern and
>   conditional branch pattern is used.
> 
> The bug in the PR was that aarch64 (and arm) did this when setting up
> the canary slot, but not when testing it.
> 
> However, it's not obvious (to me) whether this is really necessary and
> what it's really protecting against.  Even if we zero out the registers
> after these patterns, the canary value is still readily available by
> other means:
I suspect folks were just being paranoid and trying to do the right thing. The
fact there's other way to get at the data doesn't necessarily mean we should
leave it lying around in a convenient register.


> 
> (1) We don't make any effort to hide the address of the canary value
>     (typically &__stack_chk_guard, although some targets support
>     alternatives).  It's not obvious what “hiding” this address
>     would actually mean in practice, since it would often be easily
>     predictable from other non-secret addresses.
Well, isn't that only when the target doesn't support storing the guard in 
thread
local storage??   ie, I don't think you can get it consistently this way.

Now the pointer guard is a completely different story and I've been trying to 
get
that fixed for years ;(  Though I must admit it was awful nice to have it
available in a global when I needed to debug a problem related to pointer
mangling in glibc...



> 
> (2) The canary value is often available in stack locations, such as:
> 
>     (a) a canary in the current function, if the current function
>         uses stack-smash protection
> 
>     (b) a “protected” caller further up the call stack
> 
>     (c) canary values left around by previous calls, if the canary value
>         happens to occupy “dead space” in the current frame
> 
>     And being on the stack is of course fundamental to the whole scheme.
Yea, but these you have to go and find ;-)

> 

Jeff

Reply via email to