This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[AArch64][0/6] Support unwinding mangled return address in ARMv8.3-A Pointer Authentication Extension


Hi,

Several months ago, a feature called "return address signing" has been added to
GCC to prevent stack smash stack on AArch64.  For details please refer:

  https://gcc.gnu.org/ml/gcc-patches/2017-01/msg00376.html
  https://gcc.gnu.org/ml/gcc-patches/2016-11/msg03010.html

Once this feature is enabled, return address will be signed (mangled) at
function start and won't be restored to its original value until a successful
authentication during return.

This has significant impacts on frame unwinding.  Unwinders need to tell whether
return address is signed at any location in the instruction sequence and need
methods to figure out the original value of return address once it is signed.

For DWARF unwinders, a new DWARF CFA instruction DW_CFA_AARCH64_negate_ra_state
is introduced to indicate such status change from return address.  Compilers or
assembly writers are expected to put it whenever return address register is
signed or restored by hardware instructions.  During FDE scan, if
DW_CFA_AARCH64_negate_ra_state is hit, the unwinder toggles the return address
signing status and kept it in bit zero (LSB) of the new DWARF register
AARCH64_DWARF_PAUTH_RA_STATE whose value must be honored later when unwinding
the PC of upper frame using the value of return address.

Once AARCH64_DWARF_PAUTH_RA_STATE indicates return address is signed, the
following methods can be used to restore its original value:

  * Stripping the signature.
    There are two further methods, executing signature strip instructions or
    masking off it using signature bit mask.  Normally, native unwinder use the
    former and cross unwinder use the latter.  The signature bit masks are
    organized as ptrace REGSET that the debug stub can get them using ptrace
    interface and communicate their value to cross unwinder through usual
    register query.

    The ptrace support in AArch64 kernel has been posted recently:

      https://lkml.org/lkml/2017/7/19/1065
      https://lkml.org/lkml/2017/7/19/1054

  * Authenticating the signature.
    Once the authentication succeeded, return address will be restored to
    original value by hardware.  Native unwinders can do this.

For instruction scan based unwinders, they can only figure out the status of
return address through recognizing those new signing and authentication
instructions occurred in function prologue and epilogue.

This patch set let GDB AArch64 DWARF and instruction scan unwinders to support
signed return address.

The changes are:

  * The new signature bit masks ptrace REGSET is included in the new "pauth"
    feature which is added into AArch64 in Patch 1 with necessary feature
    detection code on linux native configuration.

  * gdbserver support for new "pauth" feature is added in Patch 2.

  * DWARF unwinder support is added in Patch 3.

  * Instruction scan unwinder support is added in Patch 4.

  * Core dump file support is added through Patch 5 and 6.

I have tested this patch set on an emulation environment as I don't have
ARMv8.3-A hardware.  I was using ARMv8.0-A hardware, modified GCC, modified
GLIBC and modified Binutils to emulate ARMv8.3-A Pointer Authentication
Extension.

The modified GCC will use arithmetic instruction so mangle return address and
generating the defined DWARF description, the modified GLIBC can recognize the
new ptrace regset while the modified Binutils can supply new ptrace regset
information for old core dump file.

I have run the native tests on both gdb and gdbserver, and on the following
combinations:

  1. clean gcc + clean binutils-gdb + clean GLIBC
  2. clean gcc + binutils-gdb with this patchset + clean GLIBC
  3. modified gcc + binutils-gdb with this patch set + modified GLIBC

The test result is the same for 1 and 2, and I only got ~2 new failures on 3 in
gdb/gdbserver native tests, these new failures are in gdb.thread or related with
solib.
Is this patch set OK to install once the related kernel support approved?


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]