| 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