Skip to content

[ASAN] Do not consider alignment during object size calculations #109120

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 19, 2024

Conversation

pskrgag
Copy link
Contributor

@pskrgag pskrgag commented Sep 18, 2024

It was found that ASAN logic optimizes away out-of-bound access instrumentation for over-aligned arrays. See #108287 for complete code examples.

Fix it by not considering alignment during object size calculation, since out-of-bounds access for over-aligned object is still UB and should be reported by ASAN.

Closes: #108287

@llvmbot
Copy link
Member

llvmbot commented Sep 18, 2024

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Pavel Skripkin (pskrgag)

Changes

It was found that ASAN logic optimizes away out-of-bound access instrumentation for over-aligned arrays. See #108287 for complete code examples.

Fix it by not considering alignment during object size calculation, since out-of-bounds access for over-aligned object is still UB and should be reported by ASAN.

Closes: #108287


Full diff: https://github.com/llvm/llvm-project/pull/109120.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp (+1-3)
  • (modified) llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll (+21)
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index e8a95f5dfd435c..8f1e3e0764a7f1 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -3057,9 +3057,7 @@ bool AddressSanitizer::instrumentFunction(Function &F,
                    OperandsToInstrument.size() + IntrinToInstrument.size() >
                        (unsigned)InstrumentationWithCallsThreshold);
   const DataLayout &DL = F.getDataLayout();
-  ObjectSizeOpts ObjSizeOpts;
-  ObjSizeOpts.RoundToAlign = true;
-  ObjectSizeOffsetVisitor ObjSizeVis(DL, TLI, F.getContext(), ObjSizeOpts);
+  ObjectSizeOffsetVisitor ObjSizeVis(DL, TLI, F.getContext());
 
   // Instrument.
   int NumInstrumented = 0;
diff --git a/llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll b/llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll
index 2f26a7d9f44535..bcaf54deed21cb 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll
@@ -16,6 +16,7 @@ target triple = "x86_64-unknown-linux-gnu"
 ; indexed with constants in-bounds. But instrument all other cases.
 
 @GlobSt = global [10 x i32] zeroinitializer, align 16  ; static initializer
+@GlobStAlignInBounds = global [10 x i8] zeroinitializer, align 16  ; static initializer
 @GlobDy = global [10 x i32] zeroinitializer, align 16, sanitize_address_dyninit  ; dynamic initializer
 @GlobEx = external global [10 x i32] , align 16        ; extern initializer
 
@@ -49,6 +50,26 @@ entry:
 ; CHECK: ret i32
 }
 
+; GlobStAlignInBount is accessed with out of bounds index, but in bounds of allocated area (because of alignemnt)
+define i8 @AccessGlobStAlignInBounds_0_11() sanitize_address {
+entry:
+    %0 = load i8, ptr getelementptr inbounds ([10 x i8], ptr @GlobStAlignInBounds, i64 0, i64 11), align 1
+    ret i8 %0
+; CHECK-LABEL: define i8 @AccessGlobStAlignInBounds_0_11
+; CHECK: __asan_report
+; CHECK: ret i8
+}
+
+; GlobStAlignInBount is accessed with in-bound index
+define i8 @AccessGlobStAlignInBounds_0_9() sanitize_address {
+entry:
+    %0 = load i8, ptr getelementptr inbounds ([10 x i8], ptr @GlobStAlignInBounds, i64 0, i64 9), align 1
+    ret i8 %0
+; CHECK-LABEL: define i8 @AccessGlobStAlignInBounds_0_9
+; CHECK-NOT: __asan_report
+; CHECK: ret i8
+}
+
 ; GlobDy is declared with dynamic initializer -- can't optimize.
 define i32 @AccessGlobDy_0_2() sanitize_address {
 entry:

@llvmbot
Copy link
Member

llvmbot commented Sep 18, 2024

@llvm/pr-subscribers-llvm-transforms

Author: Pavel Skripkin (pskrgag)

Changes

It was found that ASAN logic optimizes away out-of-bound access instrumentation for over-aligned arrays. See #108287 for complete code examples.

Fix it by not considering alignment during object size calculation, since out-of-bounds access for over-aligned object is still UB and should be reported by ASAN.

Closes: #108287


Full diff: https://github.com/llvm/llvm-project/pull/109120.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp (+1-3)
  • (modified) llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll (+21)
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index e8a95f5dfd435c..8f1e3e0764a7f1 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -3057,9 +3057,7 @@ bool AddressSanitizer::instrumentFunction(Function &F,
                    OperandsToInstrument.size() + IntrinToInstrument.size() >
                        (unsigned)InstrumentationWithCallsThreshold);
   const DataLayout &DL = F.getDataLayout();
-  ObjectSizeOpts ObjSizeOpts;
-  ObjSizeOpts.RoundToAlign = true;
-  ObjectSizeOffsetVisitor ObjSizeVis(DL, TLI, F.getContext(), ObjSizeOpts);
+  ObjectSizeOffsetVisitor ObjSizeVis(DL, TLI, F.getContext());
 
   // Instrument.
   int NumInstrumented = 0;
diff --git a/llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll b/llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll
index 2f26a7d9f44535..bcaf54deed21cb 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll
@@ -16,6 +16,7 @@ target triple = "x86_64-unknown-linux-gnu"
 ; indexed with constants in-bounds. But instrument all other cases.
 
 @GlobSt = global [10 x i32] zeroinitializer, align 16  ; static initializer
+@GlobStAlignInBounds = global [10 x i8] zeroinitializer, align 16  ; static initializer
 @GlobDy = global [10 x i32] zeroinitializer, align 16, sanitize_address_dyninit  ; dynamic initializer
 @GlobEx = external global [10 x i32] , align 16        ; extern initializer
 
@@ -49,6 +50,26 @@ entry:
 ; CHECK: ret i32
 }
 
+; GlobStAlignInBount is accessed with out of bounds index, but in bounds of allocated area (because of alignemnt)
+define i8 @AccessGlobStAlignInBounds_0_11() sanitize_address {
+entry:
+    %0 = load i8, ptr getelementptr inbounds ([10 x i8], ptr @GlobStAlignInBounds, i64 0, i64 11), align 1
+    ret i8 %0
+; CHECK-LABEL: define i8 @AccessGlobStAlignInBounds_0_11
+; CHECK: __asan_report
+; CHECK: ret i8
+}
+
+; GlobStAlignInBount is accessed with in-bound index
+define i8 @AccessGlobStAlignInBounds_0_9() sanitize_address {
+entry:
+    %0 = load i8, ptr getelementptr inbounds ([10 x i8], ptr @GlobStAlignInBounds, i64 0, i64 9), align 1
+    ret i8 %0
+; CHECK-LABEL: define i8 @AccessGlobStAlignInBounds_0_9
+; CHECK-NOT: __asan_report
+; CHECK: ret i8
+}
+
 ; GlobDy is declared with dynamic initializer -- can't optimize.
 define i32 @AccessGlobDy_0_2() sanitize_address {
 entry:

@pskrgag
Copy link
Contributor Author

pskrgag commented Sep 18, 2024

smth weird failed on CI TEST 'lldb-api :: functionalities/fork/concurrent_vfork/TestConcurrentVFork.py' FAILED.

seems unrelated?

@pskrgag pskrgag requested a review from vitalybuka September 18, 2024 11:33
Copy link
Collaborator

@vitalybuka vitalybuka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, CI looks unrelated

@vitalybuka vitalybuka merged commit 8a34f6d into llvm:main Sep 19, 2024
9 of 11 checks passed
@vitalybuka
Copy link
Collaborator

Thanks for the report and fix!

tmsri pushed a commit to tmsri/llvm-project that referenced this pull request Sep 19, 2024
…m#109120)

It was found that ASAN logic optimizes away out-of-bound access
instrumentation for over-aligned arrays. See llvm#108287 for complete code
examples.

Fix it by not considering alignment during object size calculation,
since out-of-bounds access for over-aligned object is still UB and
should be reported by ASAN.

Closes: llvm#108287
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[sanitizers] [ASAN] False negative on global OOB
3 participants