<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/146679>146679</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[asan][win] The memory used for PoisonShadow should be created
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
GkvJwa
</td>
</tr>
</table>
<pre>
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.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJykWFtv4roW_jXmZalV4hAIDzyEW6dH0905LXuq_RSZxIBPg41sJ5T59UfLCZAAvcyeCqmxvby8Lp_XZ5sZI1aS8yEJRyScdFhh10oP717L_-xYZ6Gy_fAb1xyEAQYkHAljCk7CCaHR2tqtIUFM6IzQ2UrYdbG4TdWG0Fmel4d_N1ut_sdTS-jMzTWEzvxuNwhDQgegJLwISby4-o14ygrDwa45bPhG6T0uLJWFVHNmeQa7NZegCymFXIFVQHpe9ZsxY38oYZR8XrNM7W5IMN3wjeH2KELoGJgElqbcGCiFypkVSsJO5DksOFgtViuueQaFzLh2VmR8UWBnZV9sYMMlTuIZCOkkqojQMWxMmRLaN8AMk5ApXlm-ZiU6JAxstVrkfIOyzwrugUmW73_xzKlxk0quDVqklrW2MY5V4Rcy4zwDBguxgkwsl1xzmfLKsPkpYEulT1FpRuTYeXS4DiqqOMbIi0slMkiSJTM2ZXkOSYK2YaKDODZMPrDt33LDtmOW5wuWvlYjj9hPaES8-NMZQGiMESF0jOL1XyEdFHFtIW2vC9t6_GLAiF-c0AHa3R85DecrPltmDS4zLrTm0s7XmrPM9ZJgBBVkQbO3KnwAiWFSWPGL66QU2hYsT1ieq7T2CAAIjdI106iU0IFbLzEusEkV-STbS7YRacKyTCPCCMWVoi2QYEqCKQRo89FlQqNzx76m182vdRMaYTBccws3EOGmai6Hsje1ZPLfl8enyW8s8o4Hg6MFfu2O9-Z7nlecnOsWKBZcJqcFSBphiut0jsF7m8WNeZepAxJMWtruuL2SYHT2oITQEaGjSyFXHjYMC1hl5PsiPHNagkllqJMn_UmFnBuUqj7dvvl8gxRbqx20wX3VWIZUSWPhgOdqqErQgq-c4w_Th2T-mDx_iyePL1XsjiFuynOZXZd3KXNwuYH4Of6rHkrunuK__v4eP93P_3HwcYmt3ETdP6v9EB-2A42-__j5eI9AOlno8nha_wbaQ2jL-PHh4X7e3vP134_4bpo8TePJy9P9fHry6yO0vGKov3G2_c6X9olnv5TkD2wl0kZY6n2O6RTGitTcYnezQPSsS3hijvj6HFPQnHNbocjBrB6_GP4AQY26O1fAHIb4W8q3SDJY9M8Y6HEJqSq0cSF4eP45doyD2QSWGwVrZmDD5B4UEgfkaiVS3My5eEWqeEH6xKqO9NmO7vjdGojss2BG4Lw98DeeFkjFS6GN_U3uqEJatcc5Z7pafab0Mdjpayyz-fdnLFhXZ5_Yo8kAlySBqpKFslZtLmr-u_JWbZvC0XVZmxuE-VfUouiCr4RsCmfiunDZ-5JUvym1OHJY02MHZYwS1qfmQHIA8dHfK6JWbY9yYokU0BSnvoNya7UDKVTZ-JxN_4BPz9y8Qq1_Sq4tej36fZ1d_z25wucODRrm-E3_Lgi3TbkfMO51TLiD5jkC4OYdBCFXN6usK2Vw2BUtPNV9NZqapYJ4seY7Lazlss0xV0oKoXGzqnwBXgCHifk2rsP-8XEz2z1X1HJNSEgLy8o-d2mY77cfi_7QyrprT7NIHUwqw8YOJuFImy2ho663JuHEtRfYjlxz9M_TdPaFcnFSE7XV-N57etDSVjE56gjPTPHftcXpiK7qOLODtu2oAhI5tJzCVUOq7Nf9ZxGvhsueG60TdpgSus5Ttut-zW2hJSQn0FT74j6eP5ZcIwL5XcF0RoLxIT-4Kw_fhI4vS8mpK1dyddnGYtRQ1rui5LwbJ77bF0zb2HY1gTZ3DdzHc-DS6j2o2i3L5S2h9OLE1XIuauyrqhS3fb9AXatPSHvZxsLVPjReGNArw7oXv3tXJfpXe0_nsMsTVHUR1nyptDsfCQsbtseb7oJby7W7G7uLtlX15bf51ICjzWqJpy-WlUymHFR12d8JmakdVhLAE5U7gbmr_m0nGwbZIBiwDh_6_dDvhgM66HbWQz9gWZ8te-lg6dPA8_1o6fd8n6XLrhcNQr8jhtSjodf3qE9p5Ae3WdpbsGCZLmkw6NFBSroe3zCR3-Z5ublVetVxbw5Dv9vr9QednC14btwDDqWS7w4vEpSEk44eukeYRbEypOvlwlhzUmOFzd3Lj2OLcELC0U7gBzTeEwqDZ73z0Ji1KvKs8YjQKXQ-_JMnIedLOaT_DwAA__8hD7Qe">