diff options
author | Michael D Kinney <michael.d.kinney@intel.com> | 2025-01-28 18:03:31 -0800 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2025-01-29 19:35:30 +0000 |
commit | 2cb8bf6c69cf78db73c6a31c0b6049741c1ea006 (patch) | |
tree | e644ea766359102942ecb0bd4d16aad2b136e2a4 | |
parent | 3600675368581ba4987f5656c2783bab62750ee7 (diff) | |
download | edk2-2cb8bf6c69cf78db73c6a31c0b6049741c1ea006.tar.gz |
UnitTestFrameworkPkg: Fix false positives from address sanitizer
PR #6408 introduced a host specific NORETURN function to resolve
false positives from the address sanitizer when LongJump() is
called and the stack is reset to a previous stack frame.
This approach was discussed here:
https://github.com/tianocore/edk2/pull/6408/files#r1918810499
False positives are still being observed with this initial
solution.
The address sanitizer provides __asan_handle_no_return()
to clean up shadow memory before a NORETURN function is
called and provides a simpler implementation for this
issue without having to introduce a host specific
NORETURN function.
https://github.com/llvm/llvm-project/blob/main/compiler-rt/include/sanitizer/asan_interface.h
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
-rw-r--r-- | UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.cpp | 46 |
1 files changed, 23 insertions, 23 deletions
diff --git a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.cpp b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.cpp index ad8487ad1b..8ed7c0988c 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.cpp +++ b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.cpp @@ -18,6 +18,17 @@ extern "C" { #include <Library/BaseLib.h>
#include <Library/UnitTestLib.h>
+ //
+ // If address sanitizer is enabled, then declare the function that is used to
+ // handle custom long jump implementation.
+ //
+ #ifdef __SANITIZE_ADDRESS__
+ void
+ __asan_handle_no_return (
+ );
+
+ #endif
+
///
/// Point to jump buffer used with SetJump()/LongJump() to test if a function
/// under test generates an expected ASSERT() condition.
@@ -25,27 +36,6 @@ extern "C" { BASE_LIBRARY_JUMP_BUFFER *gUnitTestExpectAssertFailureJumpBuffer = NULL;
/**
- LongJump wrapper for host-based unit test environments that is declared
- NORETURN to avoid false positives from address sanitizer.
-
- @param JumpBuffer A pointer to CPU context buffer.
- @param Value The value to return when the SetJump() context is
- restored and must be non-zero.
- **/
- static
- VOID
- NORETURN
- EFIAPI
- HostLongJump (
- IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer,
- IN UINTN Value
- )
- {
- LongJump (JumpBuffer, Value);
- UNREACHABLE ();
- }
-
- /**
Unit test library replacement for DebugAssert() in DebugLib.
If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
@@ -68,8 +58,18 @@ extern "C" { if (gUnitTestExpectAssertFailureJumpBuffer != NULL) {
UT_LOG_INFO ("Detected expected ASSERT: %a(%d): %a\n", FileName, LineNumber, Description);
- HostLongJump (gUnitTestExpectAssertFailureJumpBuffer, 1);
- UNREACHABLE ();
+
+ //
+ // If address sanitizer is enabled, then inform sanitizer that a no return
+ // function is being called that will reset to a previous stack frame.
+ // This is required to avoid false positives from the address sanitizer
+ // due to the use of a custom long jump implementation.
+ //
+ #ifdef __SANITIZE_ADDRESS__
+ __asan_handle_no_return ();
+ #endif
+
+ LongJump (gUnitTestExpectAssertFailureJumpBuffer, 1);
} else {
if (GetActiveFrameworkHandle () != NULL) {
AsciiStrCpyS (Message, sizeof (Message), "Detected unexpected ASSERT(");
|