Skip to content

Commit

Permalink
fix(asan): Poison memory between stack and globals
Browse files Browse the repository at this point in the history
This fixes compiler-rt/test/asan/TestCases/global-underflow.cpp , which
would sometimes fail to detect the underfloa if the tested global was the very
first one
  • Loading branch information
yuri91 committed Sep 30, 2024
1 parent 041adbb commit 63af302
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 0 deletions.
4 changes: 4 additions & 0 deletions compiler-rt/lib/asan/asan_shadow_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
# if SANITIZER_CHEERPWASM
# include "asan_poisoning.h"
extern char* volatile _stackTop;
extern char* volatile _stackBottom;
extern char* volatile _globalsStart;
# endif

namespace __asan {
Expand Down Expand Up @@ -107,6 +109,8 @@ void InitializeShadowMemory() {
// CHEERP: Poison everything from 0x0 up to stack top to detect null
// derefences
FastPoisonShadow(0, reinterpret_cast<uptr>(_stackTop), 0xfe);
// CHEERP: Poison the space between the stack and the globals
PoisonShadow(reinterpret_cast<uptr>(_stackBottom), reinterpret_cast<uptr>(_globalsStart)-reinterpret_cast<uptr>(_stackBottom), 0xfe);
# endif
CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1);
} else if (kMidMemBeg &&
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_cheerpwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

__attribute__((cheerp_asmjs)) char *volatile _stackBottom = (char *)0xdeadbeef;
__attribute__((cheerp_asmjs)) char *volatile _stackTop = (char *)0xdeadbeef;
__attribute__((cheerp_asmjs)) char *volatile _globalsStart = (char *)0xdeadbeef;

static __asan::atomic_sint32_t _collect_traces;

Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/Cheerp/LinearMemoryHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,8 @@ class LinearMemoryHelper
uint32_t stackSize;
// Stack start (it grows downwards)
uint32_t stackStart;
// Globals start
uint32_t globalsStart;
// Offset from 0x0 to the stack top. Primarily used with Asan to reserve
// the lower addresses for null pointer checks
uint32_t stackOffset;
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/CheerpUtils/LinearMemoryHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ void LinearMemoryHelper::addGlobals()
// Also, for thread locals, calculate offsets to the image start, and the total size of the image.
threadLocalImageSize = 0;
threadLocalStart = 0;
globalsStart = 0;
for (const auto G: asmjsGlobals) {
//Globalized globals do not need an address
if (globalizedGlobalsUsage.count(G))
Expand All @@ -437,6 +438,8 @@ void LinearMemoryHelper::addGlobals()
uint32_t alignment = std::max<uint32_t>(TypeSupport::getAlignmentAsmJS(targetData, ty), G->getAlignment());
// The following is correct if alignment is a power of 2 (which it should be)
heapStart = (heapStart + alignment - 1) & ~(alignment - 1);
if (globalsStart == 0)
globalsStart = heapStart;
globalAddresses.emplace(G, heapStart);
inverseGlobalAddresses.emplace(heapStart, G);
if (G->isThreadLocal())
Expand Down Expand Up @@ -688,6 +691,7 @@ void LinearMemoryHelper::addMemoryInfo()
{
setGlobalPtrIfPresent("_stackBottom", stackStart);
setGlobalPtrIfPresent("_stackTop", stackStart + 8 - stackSize);
setGlobalPtrIfPresent("_globalsStart", globalsStart);

//Align to 8 bytes
heapStart = (heapStart + 7) & ~7;
Expand Down

0 comments on commit 63af302

Please sign in to comment.