Skip to content

Commit d42863c

Browse files
committed
[msan] Fix handling of va_arg overflow area on x86_64.
The code was erroneously reading overflow area shadow from the TLS slot, bypassing the local copy. Reading shadow directly from TLS is wrong, because it can be overwritten by a nested vararg call, if that happens before va_start. llvm-svn: 189104
1 parent e3dd684 commit d42863c

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,8 +1970,7 @@ struct VarArgAMD64Helper : public VarArgHelper {
19701970
Value *OverflowArgAreaPtr = IRB.CreateLoad(OverflowArgAreaPtrPtr);
19711971
Value *OverflowArgAreaShadowPtr =
19721972
MSV.getShadowPtr(OverflowArgAreaPtr, IRB.getInt8Ty(), IRB);
1973-
Value *SrcPtr =
1974-
getShadowPtrForVAArgument(VAArgTLSCopy, IRB, AMD64FpEndOffset);
1973+
Value *SrcPtr = IRB.CreateConstGEP1_32(VAArgTLSCopy, AMD64FpEndOffset);
19751974
IRB.CreateMemCpy(OverflowArgAreaShadowPtr, SrcPtr, VAArgOverflowSize, 16);
19761975
}
19771976
}

llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,31 @@ define void @VACopy(i8* %p1, i8* %p2) nounwind uwtable sanitize_memory {
597597
; CHECK: ret void
598598

599599

600+
; Test that va_start instrumentation does not use va_arg_tls*.
601+
; It should work with a local stack copy instead.
602+
603+
%struct.__va_list_tag = type { i32, i32, i8*, i8* }
604+
declare void @llvm.va_start(i8*) nounwind
605+
606+
; Function Attrs: nounwind uwtable
607+
define void @VAStart(i32 %x, ...) {
608+
entry:
609+
%x.addr = alloca i32, align 4
610+
%va = alloca [1 x %struct.__va_list_tag], align 16
611+
store i32 %x, i32* %x.addr, align 4
612+
%arraydecay = getelementptr inbounds [1 x %struct.__va_list_tag]* %va, i32 0, i32 0
613+
%arraydecay1 = bitcast %struct.__va_list_tag* %arraydecay to i8*
614+
call void @llvm.va_start(i8* %arraydecay1)
615+
ret void
616+
}
617+
618+
; CHECK: @VAStart
619+
; CHECK: call void @llvm.va_start
620+
; CHECK-NOT: @__msan_va_arg_tls
621+
; CHECK-NOT: @__msan_va_arg_overflow_size_tls
622+
; CHECK: ret void
623+
624+
600625
; Test handling of volatile stores.
601626
; Check that MemorySanitizer does not add a check of the value being stored.
602627

0 commit comments

Comments
 (0)