llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.36k stars 12.14k forks source link

Return address not signed when combining PAC-RET with ShadowCallStack #63457

Open eugenis opened 1 year ago

eugenis commented 1 year ago

Somewhat relevant: #58072

bin/clang 1.c -target aarch64-linux-android -march=armv9-a  -c -fsanitize=shadow-call-stack -mbranch-protection=standard -S -o -
        bti     c
        str     x30, [x18], #8
        .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 // 
        paciasp
        .cfi_negate_ra_state
        sub     sp, sp, #32
        .cfi_def_cfa_offset 32
        stp     x29, x30, [sp, #16]             // 16-byte Folded Spill
        add     x29, sp, #16
        .cfi_def_cfa w29, 16
        .cfi_offset w30, -8
        .cfi_offset w29, -16
        sub     x0, x29, #4
        bl      g
        .cfi_def_cfa wsp, 32
        ldp     x29, x30, [sp, #16]             // 16-byte Folded Reload
        add     sp, sp, #32
        .cfi_def_cfa_offset 0
        autiasp
        .cfi_negate_ra_state
        ldr     x30, [x18, #-8]!
        .cfi_restore w18
        .cfi_restore w30
        .cfi_restore w29
        ret

The return address is saved unsigned on SCS, then a signed copy is saved on the regular stack. At exit, the regular stack copy is authenticated, but then an unsigned copy from SCS is used to transfer control.

It would be better to sign LR before storing to SCS and authenticate after reloading. It would also produce smaller code.

llvmbot commented 1 year ago

@llvm/issue-subscribers-backend-aarch64

eugenis commented 1 year ago

@pcc @DanielKristofKiss FYI