<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/54804>54804</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[ASAN] [x86] Thrown exceptions corrupt stack near catch site
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
stwish-msft
</td>
</tr>
</table>
<pre>
When an exception is thrown with AddressSanitizer in use, the x86 compiler fails to take into account stack red-zones added for catch bodies when determining variable addresses. Below are five examples.
```
>clang --version
clang version 14.0.0
Target: i686-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files (x86)\LLVM\bin
```
`> clang -m32 test.cpp -fsanitize=address`
``` C++
#include <stdio.h>
void one() {
// Set variables before and after caught exception.
// Variable set after thrown exception is corrupted.
puts("one");
int test = 5;
try {
throw 42;
} catch (...) {
}
int test2 = 10;
printf("%p : %d\n", &test, test);
printf("%p : %d\n", &test2, test2);
// 014FFA10 : 5
// 014FFA30 : 7213915 <-- should be 10
}
void two() {
puts("two");
// Expanding amount of stack variables show that the next 16 bytes are corrupted.
int test = 5;
try {
throw 42;
} catch (...) {
}
int vars[5] = {10, 15, 20, 25, 30};
printf("%p : %d\n", &test, test);
for (int& x : vars) {
printf("%p : %d\n", &x, x);
}
// 014FF9F0 : 5
// 014FFA00 : 67108874 <-- should be 10
// 014FFA04 : 0 <-- should be 15 (always 0)
// 014FFA08 : 22018464 <-- should be 20
// 014FFA0C : 0 <-- should be 25 (always 0)
// 014FFA10 : 30
}
void three() {
puts("three");
// Without the first variable set prior to exception throw, only 4 bytes are corrupted.
try {
throw 42;
} catch (...) {
}
int vars[5] = {10, 15, 20, 25, 30};
for (int& x : vars) {
printf("%p : %d\n", &x, x);
}
// 014FFA00 : 10
// 014FFA04 : 22018464 <-- should be 15
// 014FFA08 : 20
// 014FFA0C : 25
// 014FFA10 : 30
}
void four() {
puts("four");
// Moving all variables before thrown exception corrupt in a different pattern.
int vars[5] = {10, 15, 20, 25, 30};
try {
throw 42;
} catch (...) {
}
for (int& x : vars) {
printf("%p : %d\n", &x, x);
}
// 014FF9F0 : 10
// 014FF9F4 : 0 <-- should be 15 (always 0)
// 014FF9F8 : 22018464 <-- should be 20
// 014FF9FC : 0 <-- should be 25 (always 0)
// 014FFA00 : 30
}
void five() {
puts("five");
// Before and after also corrupt in a unique pattern.
int vars[5] = {10, 15, 20, 25, 30};
try {
throw 42;
} catch (...) {
}
int vars2[5] = {35, 40, 45, 50, 55};
for (int& x : vars) {
printf("%p : %d\n", &x, x);
}
for (int& x : vars2) {
printf("%p : %d\n", &x, x);
}
// 014FF990 : 10
// 014FF994 : 15
// 014FF998 : 20
// 014FF99C : 0 <-- should be 25 (always 0)
// 014FF9A0 : 30
// 014FF9E0 : 35
// 014FF9E4 : 22018432 <-- should be 40
// 014FF9E8 : 20 <-- should be 45 (always 20)
// 014FF9EC : 50
// 014FF9F0 : 55
}
int main() {
one();
two();
three();
four();
five();
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzVWN-PmzgQ_mvIixUEBpLwkIdsspFOak8nbdU-G2wSXx3M2SbJ9q-_sYH8Jrutdu-2EQLHY4-_mflmsMkkfZ5-W7MSkRKxfc4qw2WJuEZmreSuRDtu1mhGqWJaP5GSG_6DKcRLVGvm4TkMY2g_GaFcbiouQFQQLmC2RIZ8ZzAQWiTPZV0apA3JvyPF6PCHLJlGhFJGUSEVyonJ1yiTlEP3zsKhzDC14SUvV2hLFCeZYHaCxcG0jx6YkDtEFEMF3zKATjaVAIEXLLxg1t5HQXs1f6PHXBDQNxxumdJgZ9PfdLZdKIz9wG9nfCFqxYwXzRAfTUbDKh_ueEnlTg83epu3Y9aKEYo2kjJhR1ZS830j-qMEi4VgdMGVFc3h5iXzv5RcKbJBS_CXRh6egP88nILk06evn-GR8fK2AYfO6BG1pmwijAzTxs-rCg0L3YbIixats46zO2WAAz_Yq-nGES9zUVOGvGiuDeXSX8MCp0tuJacIQgZYASjyxu1cBD8PL-FCT8wc4qRRxiCqEK-SIlJAICHA9WptjgzzrxR87YKsQVMzqaXgGS1zqVRdGUZPNFS10Q4adhixdWZ0AhFI6HwEBi5QchAdBxj1fG6U67SroxifqfLGi5assKDv-9fuGC8utXfLY7d-GNwAUCkYVDQ2eDipkKULNCiwoXR9c_g7slpc0rnnuZE_oQJ3Oq481cYiCOPlchYGTkfSI44a8RiHURomljzDIdJrWQsK8bd2NkaeO8RRyezkLSod4-gG9KF73FdALFsYyMbVFVm0peVIQMCxgwgS4wpUyfYGhSOUPRtbdoCZt2j0AWgCBmgveUi8ZOFQwBzwI0QrTOwduzZ27SiwOt6FSrYigwLQAwPR3mlwyC6t-In19va5v4po54ZLdqXL--QLGvFoHAaTyTjuZd_1xNhNDDr4VxMTazoRO_KsUWDx9uiZOD0YB-EkHl0DwL0A5vcB4FcCaLMzupdm8Gq6WbNPEq0Z0pdq3-DtL-smiQqu9LHGuzINsQeqwBv-WKJdOthYy1I8o_iFlPstMup_SIf7rH-J3L2kDHvTqWXzC6TFffNfQcZC1uo-F5sRfVT8LLeu5Atxvc-42ii0XLP7VIIoLwqmGJChIgb2FaX_TkR5XzZ_oKrcR8B0-TbVNV3-YnVNl29UXYNXEBrOHS8Q2o3oI_TD5R6ZCC3PmVuX_J-a_d607UDiC5SRwxQ7fLFrJ66dJB-wCvctjv_L5EtfSL60Sb6-Ip-m94t8mr5N7qSz89y5kj-28j6cj6dvsQhf4Yh7FXcG9hgQnxqA71jw2Hgi6a0y7eY0uVkdLOM3BM7wN4rD4RB9FvPDeei897h9u9ied2_S8-5DPTpmzwFYd_Yf0GlE0yglA8ONYFNIytnT7E-Xl8mD_RABrS8Xr9PDqbs9ZpWMdJ9sNDdsUCsxXRtTaft9w_lpBfvGOvNzuYE_Qmy7x7BS8m-WQxYtudY1g-xdJvEkiAfrKc0ncTAOAhKPKSYp3IowieJxwMawzc_YQJCMCW0hQw6VbIecCptPyWLApzgAxoAGHAUBVKdRnjKcxRkp4oCwEfbigEFUhG9x-FKtBmrqIGX1SoNQcG30UUi05quSOQ9Z_aSGnbCaarPjej3c6MIM3PJTB_9fTUXkRQ">