Issue 180084
Summary Shadow not unpoisoned for unpacked va_arg
Labels compiler-rt:asan
Assignees
Reporter PiJoules
    ```
void func3(unsigned int);

void func2(const char *fmt, ...) {
  va_list args;
 va_start(args, fmt);

  unsigned int u = va_arg(args, unsigned int);
 func3(u);

  va_end(args);
}
```

When compiled with `clang++ -fsanitize=address -S -o - /tmp/test.cc -mllvm -asan-use-after-return=never -O3 -mllvm -asan-mapping-offset=0` produces the following asm

```
_Z5func2PKcz:                           # @_Z5func2PKcz
 .cfi_startproc
# %bb.0:                                # %entry
 pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset %rbp, -16
 movq    %rsp, %rbp
        .cfi_def_cfa_register %rbp
        pushq %rbx
        andq    $-32, %rsp
        subq    $320, %rsp # imm = 0x140
        .cfi_offset %rbx, -24
        testb   %al, %al
 je      .LBB0_8
# %bb.7:                                # %entry
 movaps  %xmm0, 160(%rsp)
        movaps  %xmm1, 176(%rsp)
 movaps  %xmm2, 192(%rsp)
        movaps  %xmm3, 208(%rsp)
        movaps %xmm4, 224(%rsp)
        movaps  %xmm5, 240(%rsp)
        movaps  %xmm6, 256(%rsp)
        movaps  %xmm7, 272(%rsp)
.LBB0_8: # %entry
        movq    %rsi, 120(%rsp)
        movq    %rdx, 128(%rsp)
        movq    %rcx, 136(%rsp)
        movq    %r8, 144(%rsp)
 movq    %r9, 152(%rsp)
        movq    $1102416563, (%rsp) # imm = 0x41B58AB3
        leaq    .L___asan_gen_stack(%rip), %rax
 movq    %rax, 8(%rsp)
        leaq    _Z5func2PKcz(%rip), %rax
        movq %rax, 16(%rsp)
        movq    %rsp, %rbx
        shrq    $3, %rbx
 movabsq $-866669180174077455, %rax      # imm = 0xF3F8F8F8F1F1F1F1
 movq    %rax, (%rbx)
        movl    $-202116109, 8(%rbx)            # imm = 0xF3F3F3F3
        movw    $0, 4(%rbx)
        movb    $0, 6(%rbx)
 movabsq $206158430216, %rax             # imm = 0x3000000008
        movq %rax, 32(%rsp)
        leaq    16(%rbp), %rax
        movq    %rax, 40(%rsp)
        leaq    112(%rsp), %rax
        movq    %rax, 48(%rsp)
 movl    $8, %eax
        cmpq    $40, %rax
        ja      .LBB0_2
# %bb.1:                                # %vaarg.in_reg
        movl    $8, %edi
        addq    48(%rsp), %rdi
        addl    $8, %eax
        movl %eax, 32(%rsp)
        jmp     .LBB0_3
.LBB0_2: # %vaarg.in_mem
        movq    40(%rsp), %rdi
        leaq 8(%rdi), %rax
        movq    %rax, 40(%rsp)
.LBB0_3: # %vaarg.end
        movq    %rdi, %rax
        shrq    $3, %rax
 movzbl  (%rax), %eax
        testb   %al, %al
        jne .LBB0_4
.LBB0_5:
        movl    (%rdi), %edi
        callq _Z5func3j@PLT
```

I believe the asan check in block `LBB0_3` can fail because RDI can point to unpoisoned shadow memory. If the first variable argument is in a register, then RDI is set in the `# %vaarg.in_reg` block as `8 + *(RSP + 48)`. The value at `RSP + 48` should be `RAX` from the prior block which is `112(%rsp)` so the value of RDI is `RSP + 120`. This make sense since the first variable argument to be unpacked should be RSI and RSI is placed there via `movq    %rsi, 120(%rsp)`.

However, nothing in the first block which does the poisoning seems to explicitly set the shadow for `RSP + 120`. The part that explicitly sets shadow is

```
        movq %rsp, %rbx
        shrq    $3, %rbx
        movabsq $-866669180174077455, %rax      # imm = 0xF3F8F8F8F1F1F1F1
        movq    %rax, (%rbx)
 movl    $-202116109, 8(%rbx)            # imm = 0xF3F3F3F3
        movw $0, 4(%rbx)
        movb    $0, 6(%rbx)
```

but it looks like only the first 12 bytes of shadow get set. The shadow byte corresponding to `RSP+120` should be the 15th byte which isn't set here. If the shadow for this region happened to be non-zero, then ASan would incorrectly diagnose an error.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to