Hi,

On Fri, Aug 7, 2020 at 6:18 AM Richard Sandiford <rsand...@gcc.gnu.org> wrote:
>
> https://gcc.gnu.org/g:5380912a17ea09a8996720fb62b1a70c16c8f9f2
>
> commit r9-8794-g5380912a17ea09a8996720fb62b1a70c16c8f9f2
> Author: Richard Sandiford <richard.sandif...@arm.com>
> Date:   Fri Aug 7 12:17:37 2020 +0100

could you please also apply this change to the gcc-8 branch?

Thanks,
Sebastian

>
>     aarch64: Clear canary value after stack_protect_test [PR96191]
>
>     The stack_protect_test patterns were leaving the canary value in the
>     temporary register, meaning that it was often still in registers on
>     return from the function.  An attacker might therefore have been
>     able to use it to defeat stack-smash protection for a later function.
>
>     gcc/
>             PR target/96191
>             * config/aarch64/aarch64.md (stack_protect_test_<mode>): Set the
>             CC register directly, instead of a GPR.  Replace the original GPR
>             destination with an extra scratch register.  Zero out operand 3
>             after use.
>             (stack_protect_test): Update accordingly.
>
>     gcc/testsuite/
>             PR target/96191
>             * gcc.target/aarch64/stack-protector-1.c: New test.
>             * gcc.target/aarch64/stack-protector-2.c: Likewise.
>
>     (cherry picked from commit fe1a26429038d7cd17abc53f96a6f3e2639b605f)
>
> Diff:
> ---
>  gcc/config/aarch64/aarch64.md                      | 34 ++++-----
>  .../gcc.target/aarch64/stack-protector-1.c         | 89 
> ++++++++++++++++++++++
>  .../gcc.target/aarch64/stack-protector-2.c         |  6 ++
>  3 files changed, 110 insertions(+), 19 deletions(-)
>
> diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
> index ed8cf8ecea1..9598bac387f 100644
> --- a/gcc/config/aarch64/aarch64.md
> +++ b/gcc/config/aarch64/aarch64.md
> @@ -6985,10 +6985,8 @@
>     (match_operand 2)]
>    ""
>  {
> -  rtx result;
>    machine_mode mode = GET_MODE (operands[0]);
>
> -  result = gen_reg_rtx(mode);
>    if (aarch64_stack_protector_guard != SSP_GLOBAL)
>    {
>      /* Generate access through the system register. The
> @@ -7013,29 +7011,27 @@
>      operands[1] = gen_rtx_MEM (mode, tmp_reg);
>    }
>    emit_insn ((mode == DImode
> -                 ? gen_stack_protect_test_di
> -                 : gen_stack_protect_test_si) (result,
> -                                               operands[0],
> -                                               operands[1]));
> -
> -  if (mode == DImode)
> -    emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, 
> const0_rtx),
> -                                   result, const0_rtx, operands[2]));
> -  else
> -    emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, 
> const0_rtx),
> -                                   result, const0_rtx, operands[2]));
> +            ? gen_stack_protect_test_di
> +            : gen_stack_protect_test_si) (operands[0], operands[1]));
> +
> +  rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
> +  emit_jump_insn (gen_condjump (gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx),
> +                               cc_reg, operands[2]));
>    DONE;
>  })
>
> +;; DO NOT SPLIT THIS PATTERN.  It is important for security reasons that the
> +;; canary value does not live beyond the end of this sequence.
>  (define_insn "stack_protect_test_<mode>"
> -  [(set (match_operand:PTR 0 "register_operand" "=r")
> -       (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
> -                    (match_operand:PTR 2 "memory_operand" "m")]
> -        UNSPEC_SP_TEST))
> +  [(set (reg:CC CC_REGNUM)
> +       (unspec:CC [(match_operand:PTR 0 "memory_operand" "m")
> +                   (match_operand:PTR 1 "memory_operand" "m")]
> +                  UNSPEC_SP_TEST))
> +   (clobber (match_scratch:PTR 2 "=&r"))
>     (clobber (match_scratch:PTR 3 "=&r"))]
>    ""
> -  "ldr\t%<w>3, %1\;ldr\t%<w>0, %2\;eor\t%<w>0, %<w>3, %<w>0"
> -  [(set_attr "length" "12")
> +  "ldr\t%<w>2, %0\;ldr\t%<w>3, %1\;subs\t%<w>2, %<w>2, %<w>3\;mov\t%3, 0"
> +  [(set_attr "length" "16")
>     (set_attr "type" "multiple")])
>
>  ;; Write Floating-point Control Register.
> diff --git a/gcc/testsuite/gcc.target/aarch64/stack-protector-1.c 
> b/gcc/testsuite/gcc.target/aarch64/stack-protector-1.c
> new file mode 100644
> index 00000000000..73e83bc413f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/stack-protector-1.c
> @@ -0,0 +1,89 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target fstack_protector } */
> +/* { dg-options "-fstack-protector-all -O2" } */
> +
> +extern volatile long *stack_chk_guard_ptr;
> +
> +volatile long *
> +get_ptr (void)
> +{
> +  return stack_chk_guard_ptr;
> +}
> +
> +void __attribute__ ((noipa))
> +f (void)
> +{
> +  volatile int x;
> +  x = 1;
> +  x += 1;
> +}
> +
> +#define CHECK(REG) "\tcmp\tx0, " #REG "\n\tbeq\t1f\n"
> +
> +asm (
> +"      .pushsection .data\n"
> +"      .align  3\n"
> +"      .globl  stack_chk_guard_ptr\n"
> +"stack_chk_guard_ptr:\n"
> +#if __ILP32__
> +"      .word   __stack_chk_guard\n"
> +#else
> +"      .xword  __stack_chk_guard\n"
> +#endif
> +"      .weak   __stack_chk_guard\n"
> +"__stack_chk_guard:\n"
> +"      .word   0xdead4321\n"
> +"      .word   0xbeef8765\n"
> +"      .text\n"
> +"      .globl  main\n"
> +"      .type   main, %function\n"
> +"main:\n"
> +"      bl      get_ptr\n"
> +"      str     x0, [sp, #-16]!\n"
> +"      bl      f\n"
> +"      str     x0, [sp, #8]\n"
> +"      ldr     x0, [sp]\n"
> +#if __ILP32__
> +"      ldr     w0, [x0]\n"
> +#else
> +"      ldr     x0, [x0]\n"
> +#endif
> +       CHECK (x1)
> +       CHECK (x2)
> +       CHECK (x3)
> +       CHECK (x4)
> +       CHECK (x5)
> +       CHECK (x6)
> +       CHECK (x7)
> +       CHECK (x8)
> +       CHECK (x9)
> +       CHECK (x10)
> +       CHECK (x11)
> +       CHECK (x12)
> +       CHECK (x13)
> +       CHECK (x14)
> +       CHECK (x15)
> +       CHECK (x16)
> +       CHECK (x17)
> +       CHECK (x18)
> +       CHECK (x19)
> +       CHECK (x20)
> +       CHECK (x21)
> +       CHECK (x22)
> +       CHECK (x23)
> +       CHECK (x24)
> +       CHECK (x25)
> +       CHECK (x26)
> +       CHECK (x27)
> +       CHECK (x28)
> +       CHECK (x29)
> +       CHECK (x30)
> +"      ldr     x1, [sp]\n"
> +       CHECK (x1)
> +"      mov     x0, #0\n"
> +"      b       exit\n"
> +"1:\n"
> +"      b       abort\n"
> +"      .size   main, .-main\n"
> +"      .popsection"
> +);
> diff --git a/gcc/testsuite/gcc.target/aarch64/stack-protector-2.c 
> b/gcc/testsuite/gcc.target/aarch64/stack-protector-2.c
> new file mode 100644
> index 00000000000..266c36fdbc6
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/stack-protector-2.c
> @@ -0,0 +1,6 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target fstack_protector } */
> +/* { dg-require-effective-target fpic } */
> +/* { dg-options "-fstack-protector-all -O2 -fpic" } */
> +
> +#include "stack-protector-1.c"

Reply via email to