Issue 141070
Summary The aarch64 trampoline of llvm-xray is unsound at tailcall
Labels new issue
Assignees
Reporter 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](https://github.com/user-attachments/assets/93a7b1a5-cf02-4aa3-a0ba-ad2413e9ad6e)

Since tailcall trampoline (it's actually exit trampoline, because https://github.com/llvm/llvm-project/issues/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

```c
#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

```shell
$ 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)
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to