kovdan01 wrote:

@atrosinenko Here is a reproducer IR code.

<details>

```
define void @_ZN7myshape4moveEv(ptr %this) #0 {
entry:
  %0 = load ptr, ptr %this, align 8
  %vtable = load ptr, ptr %0, align 8
  %1 = ptrtoint ptr %0 to i64
  %2 = tail call i64 @llvm.ptrauth.blend(i64 %1, i64 50297)
  %3 = ptrtoint ptr %vtable to i64
  %4 = tail call i64 @llvm.ptrauth.auth(i64 %3, i32 2, i64 %2)
  %5 = inttoptr i64 %4 to ptr
  %6 = load ptr, ptr %5, align 8
  %7 = tail call i64 @llvm.ptrauth.blend(i64 %4, i64 36564)
  tail call void %6(ptr noundef nonnull align 8 dereferenceable(8) %0) [ 
"ptrauth"(i32 0, i64 %7) ]
  %r = getelementptr inbounds i8, ptr %this, i64 8
  %8 = load ptr, ptr %r, align 8
  %vtable2 = load ptr, ptr %8, align 8
  %9 = ptrtoint ptr %8 to i64
  %10 = tail call i64 @llvm.ptrauth.blend(i64 %9, i64 50297)
  %11 = ptrtoint ptr %vtable2 to i64
  %12 = tail call i64 @llvm.ptrauth.auth(i64 %11, i32 2, i64 %10)
  %13 = inttoptr i64 %12 to ptr
  %14 = load ptr, ptr %13, align 8
  %15 = tail call i64 @llvm.ptrauth.blend(i64 %12, i64 36564)
  tail call void %14(ptr noundef nonnull align 8 dereferenceable(8) %8) [ 
"ptrauth"(i32 0, i64 %15) ]
  ret void
}

declare i64 @llvm.ptrauth.blend(i64, i64)

declare i64 @llvm.ptrauth.auth(i64, i32 immarg, i64)

attributes #0 = { "ptrauth-auth-traps" "ptrauth-calls" "ptrauth-returns" }
```

</details>

When compiled with `llc -O3 -mtriple aarch64-linux-gnu -mattr=+pauth`, the 
following assembly is generated. X16 register is clobbered during check 
inserted under `else if (Method == AuthCheckMethod::HighBitsNoTBI)`. The 
previous value (containing pointer for address discrimination) is not spilled 
before and not restored after that. So, the last `braa` instructio uses 
incorrect discrimination value in X16 register, which results in authentication 
failure and trying to pass control to an address with non-zero pac field, 
causing a segfault. nProbably, a different scratch register (e.g. X17) should 
be used for check sequence if X16 is already in use for address discrimination.

<details>

```
_ZN7myshape4moveEv:                     // @_ZN7myshape4moveEv
        .cfi_startproc
// %bb.0:                               // %entry
        .cfi_b_key_frame
        pacibsp
        stp     x30, x19, [sp, #-16]!           // 16-byte Folded Spill
        .cfi_negate_ra_state
        .cfi_def_cfa_offset 16
        .cfi_offset w19, -8
        .cfi_offset w30, -16
        mov     x19, x0
        ldr     x0, [x0]
        ldr     x16, [x0]
        mov     x17, x0
        movk    x17, #50297, lsl #48
        autda   x16, x17
        mov     x17, x16
        xpacd   x17
        cmp     x16, x17
        b.eq    .Lauth_success_0
        brk     #0xc472
.Lauth_success_0:
        ldr     x9, [x16]
        mov     x8, x16
        mov     x17, x8
        movk    x17, #36564, lsl #48
        blraa   x9, x17
        ldr     x0, [x19, #8]
        ldr     x16, [x0]
        mov     x17, x0
        movk    x17, #50297, lsl #48
        autda   x16, x17
        mov     x17, x16
        xpacd   x17
        cmp     x16, x17
        b.eq    .Lauth_success_1
        brk     #0xc472
.Lauth_success_1:
        ldr     x1, [x16]
        ldp     x30, x19, [sp], #16             // 16-byte Folded Reload
        autibsp
        eor     x16, x30, x30, lsl #1
        tbz     x16, #62, .Lauth_success_2
        brk     #0xc471
.Lauth_success_2:
        movk    x16, #36564, lsl #48
        braa    x1, x16
```

</details>

The IR corresponds to the following C++ code.

<details>

```
struct shape {
  virtual void move() = 0;
};

struct line : public shape {
  void move () override;
};

struct myshape {
  line *l;
  line *r;
  void move();
};

void myshape::move() {
  l->move();
  r->move();
}
```

</details>


https://github.com/llvm/llvm-project/pull/110705
_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to