Skip to content

The aarch64 trampoline of llvm-xray is unsound at tailcall #141070

Open
@quininer

Description

@quininer

All trampolines in aarch64 do not backup the local variable register. https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/xray/xray_trampoline_AArch64.S#L4
this is unsound in tailcall functions that use function pointer.

Image

Since tailcall trampoline (it's actually exit trampoline, because #141051) does not backup x9 register, it is possible to corrupt x9 during an xray rt call. the br instruction will then jump to corrupted address.

I can reproduce the crash using the following code

#include <stdint.h>

typedef struct Func {
  int(*ptr)(
    unsigned long a0,
    unsigned long a1,
    unsigned long a2,
    unsigned long a3,
    unsigned long a4,
    unsigned long a5,
    unsigned long a6,
    unsigned long a7
  );
} func_t;

__attribute__ ((noinline))
int fx(
  unsigned long a0,
  unsigned long a1,
  unsigned long a2,
  unsigned long a3,
  unsigned long a4,
  unsigned long a5,
  unsigned long a6,
  unsigned long a7
) {
  return a0
    + a1
    - a2
    * a3
    / a4
    ^ a5
    & a6
    << a7
  ;
}

__attribute__ ((noinline))
int foo(
  unsigned long a0,
  unsigned long a1,
  unsigned long a2,
  unsigned long a3,
  unsigned long a4,
  unsigned long a5,
  unsigned long a6,
  unsigned long a7,
  struct Func *f
) {
  unsigned long n1 = a1 + a2;
  unsigned long n2 = a3 - a4;
  
  
  return ((*f).ptr)(
    n1,
    n2 ? a1 : a2,
    a2,
    a3,
    a4,
    a5,
    a6,
    a7
  );
}

int main() {
  struct Func func = { fx };
  
  foo(
    1,
    2,
    3,
    4,
    5,
    6,
    7,
    8,
    &func
  );
}

and

$ clang foo.c -O2 -fxray-instrument -fxray-instruction-threshold=1 -fuse-ld=lld
$ env XRAY_OPTIONS="patch_premain=true verbosity=1 xray_mode=xray-basic" ./a.out
==15386==XRay: Log file in 'xray-log.a.out.JQTDQR'
fish: Job 1, 'env XRAY_OPTIONS="patch_premain…' terminated by signal SIGSEGV (Address boundary error)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions