From a99f2a1277c4e63b10a5d9169aca9ec0d5e3ea0d Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Thu, 23 Nov 2017 08:34:32 +0000 Subject: [PATCH] [MSan] Move the access address check before the shadow access for that address MSan used to insert the shadow check of the store pointer operand _after_ the shadow of the value operand has been written. This happens to work in the userspace, as the whole shadow range is always mapped. However in the kernel the shadow page may not exist, so the bug may cause a crash. This patch moves the address check in front of the shadow access. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@318901 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Instrumentation/MemorySanitizer.cpp | 3 +-- .../MemorySanitizer/check_access_address.ll | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 459e2b39b32..30b15195e8c 100644 --- a/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -830,10 +830,9 @@ struct MemorySanitizerVisitor : public InstVisitor { StoreInst *NewSI = IRB.CreateAlignedStore(Shadow, ShadowPtr, SI->getAlignment()); DEBUG(dbgs() << " STORE: " << *NewSI << "\n"); - (void)NewSI; if (ClCheckAccessAddress) - insertShadowCheck(Addr, SI); + insertShadowCheck(Addr, NewSI); if (SI->isAtomic()) SI->setOrdering(addReleaseOrdering(SI->getOrdering())); diff --git a/test/Instrumentation/MemorySanitizer/check_access_address.ll b/test/Instrumentation/MemorySanitizer/check_access_address.ll index 723d6f0cd34..c01d3eec70c 100644 --- a/test/Instrumentation/MemorySanitizer/check_access_address.ll +++ b/test/Instrumentation/MemorySanitizer/check_access_address.ll @@ -26,3 +26,25 @@ entry: ; CHECK-LABEL: @ByValArgumentShadowSmallAlignment ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 2, i32 2, i1 false) ; CHECK: ret i16 + + +; Check instrumentation of stores. The check must precede the shadow store. + +define void @Store(i32* nocapture %p, i32 %x) nounwind uwtable sanitize_memory { +entry: + store i32 %x, i32* %p, align 4 + ret void +} + +; CHECK-LABEL: @Store +; CHECK: load {{.*}} @__msan_param_tls +; CHECK: icmp +; CHECK: br i1 +; CHECK: