Issue |
146679
|
Summary |
[asan][win] The memory used for PoisonShadow should be created
|
Labels |
new issue
|
Assignees |
|
Reporter |
GkvJwa
|
Here is a [issue](https://github.com/llvm/llvm-project/issues/144355) on Win
Because the memory is not created when running to ```FastPoisonShadow->memset```, an access violation will be triggered under the debugger
As mentioned in the issue, msvc's asan does not have this problem, So I analyzed the asan version of msvc, there is indeed a big difference
The memory for ```PoisonShadow``` will be created
```
void __fastcall __asan::AsanMapUnmapCallback::OnMap(
__asan::AsanMapUnmapCallback *this,
unsigned __int64 p,
unsigned __int64 size)
{
__asan::AsanStats *CurrentThreadStats; // rax
_sanitizer_virtual_alloc(
(char *)_asan_shadow_memory_dynamic_address + (p >> 3),
(unsigned __int64)_asan_shadow_memory_dynamic_address
+ ((size + p - 8) >> 3)
- ((_QWORD)_asan_shadow_memory_dynamic_address
+ (p >> 3))
+ 1,
0x1000u,
4u);
__asan::PoisonShadow(p, size, 0xFAu);
CurrentThreadStats = __asan::GetCurrentThreadStats();
++CurrentThreadStats->mmaps;
CurrentThreadStats->mmaped += size;
}
-->
void AsanMapUnmapCallback::OnMap(uptr p, uptr size) const {
uptr shadow_beg = MEM_TO_SHADOW(p);
uptr shadow_end = MEM_TO_SHADOW(p + size - ASAN_SHADOW_GRANULARITY) + 1;
VirtualAlloc((LPVOID)shadow_beg, shadow_end - shadow_beg, MEM_COMMIT,
PAGE_READWRITE);
PoisonShadow(p, size, kAsanHeapLeftRedzoneMagic);
// Statistics.
AsanStats &thread_stats = GetCurrentThreadStats();
thread_stats.mmaps++;
thread_stats.mmaped += size;
}
```
To avoid exceptions in debugger
Of course, MSVC's ASAN also has many other logics
like
When calling PoisonShadow, _sanitizer_virtual_alloc is basically executed first
```
void __fastcall __asan::AsanThread::ClearShadowForThreadStackAndTLS(__asan::AsanThread *this)
{
unsigned __int64 stack_bottom; // rax
unsigned __int64 stack_top; // r8
unsigned __int64 tls_end; // rax
unsigned __int64 tls_begin; // rdi
unsigned __int64 v6; // rdi
unsigned __int64 v7; // rbx
stack_bottom = this->stack_bottom_;
stack_top = this->stack_top_;
if ( stack_top != stack_bottom )
{
_sanitizer_virtual_alloc(
(char *)_asan_shadow_memory_dynamic_address + (stack_bottom >> 3),
(unsigned __int64)_asan_shadow_memory_dynamic_address
+ ((stack_top - 8) >> 3)
- ((_QWORD)_asan_shadow_memory_dynamic_address
+ (stack_bottom >> 3))
+ 1,
0x1000u,
4u);
__asan::PoisonShadow(this->stack_bottom_, this->stack_top_ - this->stack_bottom_, 0);
}
tls_end = this->tls_end_;
```
rewritten VirtualAlloc
```
void *__fastcall _sanitizer_virtual_alloc(
void *lpAddress,
unsigned __int64 dwSize,
unsigned int flAllocationType,
unsigned int flProtect)
{
void *v5; // [rsp+40h] [rbp+8h] BYREF
unsigned __int64 v6; // [rsp+48h] [rbp+10h] BYREF
unsigned int v7; // [rsp+50h] [rbp+18h] BYREF
unsigned int v8; // [rsp+58h] [rbp+20h] BYREF
v8 = flProtect;
v7 = flAllocationType;
v6 = dwSize;
v5 = lpAddress;
return __sanitizer::IATOverwriteGuard<void * (void *,unsigned __int64,unsigned long,unsigned long),void * &,unsigned __int64 &,unsigned long &,unsigned long &>(
"VirtualAlloc IAT entry overwritten.",
(void *(__fastcall *)(void *, unsigned __int64, unsigned int, unsigned int))VirtualAlloc,
&v5,
&v6,
&v7,
&v8);
}
```
Therefore, it may be better for asan to create the memory for PoisonShadow in advance on the windows, like MSVC does.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs