[compiler-rt] [asan][test] Distinguish real and fake stack shadow in Windows SEH (PR #226343)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 24 19:51:53 PDT 2026


https://github.com/kingakasa created https://github.com/llvm/llvm-project/pull/226343

The Windows SEH tests currently expect a local buffer's redzone to be unpoisoned after exception handling. That describes the existing real-stack cleanup behavior, but is incorrect when use-after-return detection places the still-live local buffer on the fake stack: its redzone should remain poisoned.

Query whether the buffer belongs to the current fake stack and check the corresponding shadow state. Apply the same distinction to seh.cpp and dll_seh.cpp. This preserves coverage of the existing real-stack behavior and checks that live fake-stack redzones survive the transfer.

Validation:
- Before this change, both tests fail with detect_stack_use_after_return=true and pass with it false in the dynamic CRT control.
- After the change, both tests pass under default settings and with detect_stack_use_after_return explicitly true and false, for dynamic and static CRT configurations: 12/12 lit executions.
- These are test-only changes, exercised against the unmodified baseline compiler and runtime.

Tested independently on Windows x64 using a fresh Release LLVM/Clang build with assertions enabled and a matching Release ASan runtime, based on `6dc4a4ba2850369afd537001377fb9d404653d26`.

Changed-line clang-format and git diff --check pass.

Assisted-by: OpenAI Codex


>From 4a407c8a0b1a82f96e67b70d401b9bb5e59b686f Mon Sep 17 00:00:00 2001
From: Kinga Kasa <kasakinga14 at gmail.com>
Date: Thu, 24 Sep 2026 22:50:03 -0400
Subject: [PATCH 1/2] [asan][test] Distinguish real and fake stack shadow in
 Windows SEH

The Windows SEH tests currently expect a local buffer's redzone to be unpoisoned after exception handling. That describes the existing real-stack cleanup behavior, but is incorrect when use-after-return detection places the still-live local buffer on the fake stack: its redzone should remain poisoned.

Query whether the buffer belongs to the current fake stack and check the corresponding shadow state. Apply the same distinction to seh.cpp and dll_seh.cpp. This preserves coverage of the existing real-stack behavior and checks that live fake-stack redzones survive the transfer.

Validation:
- Before this change, both tests fail with detect_stack_use_after_return=true and pass with it false in the dynamic CRT control.
- After the change, both tests pass under default settings and with detect_stack_use_after_return explicitly true and false, for dynamic and static CRT configurations: 12/12 lit executions.
- These are test-only changes, exercised against the unmodified baseline compiler and runtime.

Tested independently on Windows x64 using a fresh Release LLVM/Clang build with assertions enabled and a matching Release ASan runtime, based on `6dc4a4ba2850369afd537001377fb9d404653d26`.

Changed-line clang-format and git diff --check pass.

Assisted-by: OpenAI Codex
---
 .../test/asan/TestCases/Windows/msvc/dll_seh.cpp       | 10 +++++++---
 compiler-rt/test/asan/TestCases/Windows/msvc/seh.cpp   | 10 +++++++---
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/compiler-rt/test/asan/TestCases/Windows/msvc/dll_seh.cpp b/compiler-rt/test/asan/TestCases/Windows/msvc/dll_seh.cpp
index 9a29bee75c1b57..85c01f8b575179 100644
--- a/compiler-rt/test/asan/TestCases/Windows/msvc/dll_seh.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/msvc/dll_seh.cpp
@@ -14,6 +14,8 @@
 // Should just "#include <sanitizer/asan_interface.h>" when C++ exceptions are
 // supported and we don't need to use CL.
 extern "C" bool __asan_address_is_poisoned(void *p);
+extern "C" void *__asan_get_current_fake_stack();
+extern "C" void *__asan_addr_is_in_fake_stack(void *, void *, void **, void **);
 
 void ThrowAndCatch();
 
@@ -43,8 +45,10 @@ int test_function() {
   ThrowAndCatch();
   fprintf(stderr, "After:  %p poisoned: %d\n",  &x,
           __asan_address_is_poisoned(x + 32));
-  // FIXME: Invert this assertion once we fix
-  // https://code.google.com/p/address-sanitizer/issues/detail?id=258
-  assert(!__asan_address_is_poisoned(x + 32));
+  // Exception handling currently clears real-stack redzones (issue 258).
+  // A live fake-stack allocation must retain its redzones.
+  bool on_fake_stack = __asan_addr_is_in_fake_stack(
+      __asan_get_current_fake_stack(), x, nullptr, nullptr) != nullptr;
+  assert(__asan_address_is_poisoned(x + 32) == on_fake_stack);
   return 0;
 }
diff --git a/compiler-rt/test/asan/TestCases/Windows/msvc/seh.cpp b/compiler-rt/test/asan/TestCases/Windows/msvc/seh.cpp
index f3c7e1a33a568f..83d91e94337b4b 100644
--- a/compiler-rt/test/asan/TestCases/Windows/msvc/seh.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/msvc/seh.cpp
@@ -20,6 +20,8 @@
 // Should just "#include <sanitizer/asan_interface.h>" when C++ exceptions are
 // supported and we don't need to use CL.
 extern "C" bool __asan_address_is_poisoned(void *p);
+extern "C" void *__asan_get_current_fake_stack();
+extern "C" void *__asan_addr_is_in_fake_stack(void *, void *, void **, void **);
 
 void ThrowAndCatch();
 
@@ -51,8 +53,10 @@ int main() {
   ThrowAndCatch();
   fprintf(stderr, "After:  %p poisoned: %d\n",  &x,
           __asan_address_is_poisoned(x + 32));
-  // FIXME: Invert this assertion once we fix
-  // https://code.google.com/p/address-sanitizer/issues/detail?id=258
-  assert(!__asan_address_is_poisoned(x + 32));
+  // Exception handling currently clears real-stack redzones (issue 258).
+  // A live fake-stack allocation must retain its redzones.
+  bool on_fake_stack = __asan_addr_is_in_fake_stack(
+      __asan_get_current_fake_stack(), x, nullptr, nullptr) != nullptr;
+  assert(__asan_address_is_poisoned(x + 32) == on_fake_stack);
 }
 #endif

>From 19ef8d660a1c42b6dc0eaae031b632e2429295a8 Mon Sep 17 00:00:00 2001
From: Kinga Kasa <kasakinga14 at gmail.com>
Date: Thu, 24 Sep 2026 22:50:03 -0400
Subject: [PATCH 2/2] [style] Format seh-shadow-tests changes

Apply the upstream changed-line clang-format configuration.
No functional changes.

Assisted-by: OpenAI Codex
---
 compiler-rt/test/asan/TestCases/Windows/msvc/dll_seh.cpp | 5 +++--
 compiler-rt/test/asan/TestCases/Windows/msvc/seh.cpp     | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/compiler-rt/test/asan/TestCases/Windows/msvc/dll_seh.cpp b/compiler-rt/test/asan/TestCases/Windows/msvc/dll_seh.cpp
index 85c01f8b575179..99481f54afc1c3 100644
--- a/compiler-rt/test/asan/TestCases/Windows/msvc/dll_seh.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/msvc/dll_seh.cpp
@@ -47,8 +47,9 @@ int test_function() {
           __asan_address_is_poisoned(x + 32));
   // Exception handling currently clears real-stack redzones (issue 258).
   // A live fake-stack allocation must retain its redzones.
-  bool on_fake_stack = __asan_addr_is_in_fake_stack(
-      __asan_get_current_fake_stack(), x, nullptr, nullptr) != nullptr;
+  bool on_fake_stack =
+      __asan_addr_is_in_fake_stack(__asan_get_current_fake_stack(), x, nullptr,
+                                   nullptr) != nullptr;
   assert(__asan_address_is_poisoned(x + 32) == on_fake_stack);
   return 0;
 }
diff --git a/compiler-rt/test/asan/TestCases/Windows/msvc/seh.cpp b/compiler-rt/test/asan/TestCases/Windows/msvc/seh.cpp
index 83d91e94337b4b..d9bbd4337c28af 100644
--- a/compiler-rt/test/asan/TestCases/Windows/msvc/seh.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/msvc/seh.cpp
@@ -55,8 +55,9 @@ int main() {
           __asan_address_is_poisoned(x + 32));
   // Exception handling currently clears real-stack redzones (issue 258).
   // A live fake-stack allocation must retain its redzones.
-  bool on_fake_stack = __asan_addr_is_in_fake_stack(
-      __asan_get_current_fake_stack(), x, nullptr, nullptr) != nullptr;
+  bool on_fake_stack =
+      __asan_addr_is_in_fake_stack(__asan_get_current_fake_stack(), x, nullptr,
+                                   nullptr) != nullptr;
   assert(__asan_address_is_poisoned(x + 32) == on_fake_stack);
 }
 #endif



More information about the llvm-commits mailing list