[llvm] 5b5d774 - [hwasan] Respect returns attribute when tracking values.

Florian Mayer via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 13 12:52:43 PDT 2021


Author: Florian Mayer
Date: 2021-09-13T20:52:24+01:00
New Revision: 5b5d774f5d3840a1e242f0ef5873d735ccf817a4

URL: https://github.com/llvm/llvm-project/commit/5b5d774f5d3840a1e242f0ef5873d735ccf817a4
DIFF: https://github.com/llvm/llvm-project/commit/5b5d774f5d3840a1e242f0ef5873d735ccf817a4.diff

LOG: [hwasan] Respect returns attribute when tracking values.

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D109233

Added: 
    

Modified: 
    llvm/lib/Analysis/StackSafetyAnalysis.cpp
    llvm/test/Analysis/StackSafetyAnalysis/local.ll
    llvm/test/Instrumentation/HWAddressSanitizer/stack-safety-analysis.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/StackSafetyAnalysis.cpp b/llvm/lib/Analysis/StackSafetyAnalysis.cpp
index 18e303e55a599..9f22b27b45408 100644
--- a/llvm/lib/Analysis/StackSafetyAnalysis.cpp
+++ b/llvm/lib/Analysis/StackSafetyAnalysis.cpp
@@ -406,6 +406,11 @@ void StackSafetyLocalAnalysis::analyzeAllUses(Value *Ptr,
         }
 
         const auto &CB = cast<CallBase>(*I);
+        if (CB.getReturnedArgOperand() == V) {
+          if (Visited.insert(I).second)
+            WorkList.push_back(cast<const Instruction>(I));
+        }
+
         if (!CB.isArgOperand(&UI)) {
           US.addRange(I, UnknownRange);
           break;

diff  --git a/llvm/test/Analysis/StackSafetyAnalysis/local.ll b/llvm/test/Analysis/StackSafetyAnalysis/local.ll
index 6c0fbef8a2661..7a63a8c44efd2 100644
--- a/llvm/test/Analysis/StackSafetyAnalysis/local.ll
+++ b/llvm/test/Analysis/StackSafetyAnalysis/local.ll
@@ -12,6 +12,7 @@ declare void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 %isvo
 declare void @llvm.memset.p0i8.i64(i8* %dest, i8 %val, i64 %len, i1 %isvolatile)
 
 declare void @unknown_call(i8* %dest)
+declare i8* @retptr(i8* returned)
 
 ; Address leaked.
 define void @LeakAddress() {
@@ -90,6 +91,23 @@ entry:
   ret void
 }
 
+define void @StoreInBounds6() {
+; CHECK-LABEL: @StoreInBounds6 dso_preemptable{{$}}
+; CHECK-NEXT: args uses:
+; CHECK-NEXT: allocas uses:
+; GLOBAL-NEXT: x[4]: full-set, @retptr(arg0, [0,1)){{$}}
+; LOCAL-NEXT: x[4]: [0,1), @retptr(arg0, [0,1)){{$}}
+; GLOBAL-NEXT: safe accesses:
+; GLOBAL-NEXT: store i8 0, i8* %x2, align 1
+; CHECK-EMPTY:
+entry:
+  %x = alloca i32, align 4
+  %x1 = bitcast i32* %x to i8*
+  %x2 = call i8* @retptr(i8* %x1)
+  store i8 0, i8* %x2, align 1
+  ret void
+}
+
 define dso_local void @WriteMinMax(i8* %p) {
 ; CHECK-LABEL: @WriteMinMax{{$}}
 ; CHECK-NEXT: args uses:
@@ -135,6 +153,24 @@ entry:
   ret void
 }
 
+define void @StoreOutOfBounds2() {
+; CHECK-LABEL: @StoreOutOfBounds2 dso_preemptable{{$}}
+; CHECK-NEXT: args uses:
+; CHECK-NEXT: allocas uses:
+; GLOBAL-NEXT: x[4]: full-set, @retptr(arg0, [2,3)){{$}}
+; LOCAL-NEXT: x[4]: [2,6), @retptr(arg0, [2,3)){{$}}
+; GLOBAL-NEXT: safe accesses:
+; CHECK-EMPTY:
+entry:
+  %x = alloca i32, align 4
+  %x1 = bitcast i32* %x to i8*
+  %x2 = getelementptr i8, i8* %x1, i64 2
+  %x3 = call i8* @retptr(i8* %x2)
+  %x4 = bitcast i8* %x3 to i32*
+  store i32 0, i32* %x4, align 1
+  ret void
+}
+
 ; There is no 
diff erence in load vs store handling.
 define void @LoadInBounds() {
 ; CHECK-LABEL: @LoadInBounds dso_preemptable{{$}}

diff  --git a/llvm/test/Instrumentation/HWAddressSanitizer/stack-safety-analysis.ll b/llvm/test/Instrumentation/HWAddressSanitizer/stack-safety-analysis.ll
index a71f950105877..b14445bde1f03 100644
--- a/llvm/test/Instrumentation/HWAddressSanitizer/stack-safety-analysis.ll
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/stack-safety-analysis.ll
@@ -155,6 +155,25 @@ entry:
   ret i32 0
 }
 
+; Check whether we see through the returns attribute of functions.
+define i32 @test_retptr(i32* %a) sanitize_hwaddress {
+entry:
+  ; CHECK-LABEL: @test_retptr
+  ; NOSAFETY: call {{.*}}__hwasan_generate_tag
+  ; NOSAFETY: call {{.*}}__hwasan_store
+  ; SAFETY: call {{.*}}__hwasan_generate_tag
+  ; SAFETY-NOT: call {{.*}}__hwasan_store
+  ; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
+  ; TODO: Do not emit this store.
+  ; NOSTACK: call {{.*}}__hwasan_store
+  %buf.sroa.0 = alloca i8, align 4
+  call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %buf.sroa.0)
+  %ptr = call i8* @retptr(i8* %buf.sroa.0)
+  store volatile i8 0, i8* %ptr, align 4, !tbaa !8
+  call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull %buf.sroa.0)
+  ret i32 0
+}
+
 ; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn
 declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
 
@@ -165,6 +184,7 @@ declare i1 @cond()
 declare void @use(i8* nocapture)
 declare i32 @getoffset()
 declare i8* @getptr(i8* nocapture)
+declare i8* @retptr(i8* returned)
 
 !8 = !{!9, !9, i64 0}
 !9 = !{!"omnipotent char", !10, i64 0}


        


More information about the llvm-commits mailing list