Skip to content

Commit 868e1ee

Browse files
committed
Revert "[libasan] Remove 4Mb stack limit for swapcontext unpoisoning"
This patches exposed existing incorectness of swapcontext imlementation. swapcontext does not set oucp->uc_stack. Unpoisoning works if ucp is from makecontext, but may try to use garbage pointers if it's from previos swapcontext or from getcontext. Existing limit reduces probability of garbage pointers are used. I restore behavour which we had for years, and will look to improve swapcontext support. This reverts commit d0751c9.
1 parent ad94b5c commit 868e1ee

File tree

2 files changed

+3
-53
lines changed

2 files changed

+3
-53
lines changed

compiler-rt/lib/asan/asan_interceptors.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,8 @@ static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) {
248248
uptr bottom = stack & ~(PageSize - 1);
249249
ssize += stack - bottom;
250250
ssize = RoundUpTo(ssize, PageSize);
251-
if (AddrIsInMem(bottom) && ssize)
251+
static const uptr kMaxSaneContextStackSize = 1 << 22; // 4 Mb
252+
if (AddrIsInMem(bottom) && ssize && ssize <= kMaxSaneContextStackSize)
252253
PoisonShadow(bottom, ssize, 0);
253254
}
254255

compiler-rt/test/asan/TestCases/Linux/swapcontext_annotation.cpp

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -146,61 +146,9 @@ int Run(int arg, int mode, char *child_stack) {
146146
return child_stack[arg];
147147
}
148148

149-
ucontext_t orig_huge_stack_context;
150-
ucontext_t child_huge_stack_context;
151-
152-
// There used to be a limitation for stack unpoisoning (size <= 4Mb), check that it's gone.
153-
const int kHugeStackSize = 1 << 23;
154-
155-
void ChildHugeStack() {
156-
__sanitizer_finish_switch_fiber(nullptr, &main_thread_stack,
157-
&main_thread_stacksize);
158-
char x[32] = {0}; // Stack gets poisoned.
159-
__sanitizer_start_switch_fiber(nullptr, main_thread_stack,
160-
main_thread_stacksize);
161-
if (swapcontext(&child_huge_stack_context, &orig_huge_stack_context) < 0) {
162-
perror("swapcontext");
163-
_exit(1);
164-
}
165-
}
166-
167-
void DoRunHugeStack(char *child_stack) {
168-
getcontext(&child_huge_stack_context);
169-
child_huge_stack_context.uc_stack.ss_sp = child_stack;
170-
child_huge_stack_context.uc_stack.ss_size = kHugeStackSize;
171-
makecontext(&child_huge_stack_context, (void (*)())ChildHugeStack, 0);
172-
void *fake_stack_save;
173-
__sanitizer_start_switch_fiber(&fake_stack_save,
174-
child_huge_stack_context.uc_stack.ss_sp,
175-
child_huge_stack_context.uc_stack.ss_size);
176-
if (swapcontext(&orig_huge_stack_context, &child_huge_stack_context) < 0) {
177-
perror("swapcontext");
178-
_exit(1);
179-
}
180-
__sanitizer_finish_switch_fiber(
181-
fake_stack_save, (const void **)&child_huge_stack_context.uc_stack.ss_sp,
182-
&child_huge_stack_context.uc_stack.ss_size);
183-
for (int i = 0; i < kHugeStackSize; ++i) {
184-
child_stack[i] = i;
185-
}
186-
}
187-
188-
void RunHugeStack() {
189-
const int run_offset = 1 << 14;
190-
char *heap = new char[kHugeStackSize + run_offset + 1];
191-
DoRunHugeStack(heap);
192-
DoRunHugeStack(heap + run_offset);
193-
DoRunHugeStack(heap);
194-
delete[] heap;
195-
}
196-
197149
void handler(int sig) { CallNoReturn(); }
198150

199151
int main(int argc, char **argv) {
200-
// CHECK: WARNING: ASan doesn't fully support makecontext/swapcontext
201-
// CHECK-NOT: ASan is ignoring requested __asan_handle_no_return
202-
RunHugeStack();
203-
204152
// set up a signal that will spam and trigger __asan_handle_no_return at
205153
// tricky moments
206154
struct sigaction act = {};
@@ -222,6 +170,7 @@ int main(int argc, char **argv) {
222170
char *heap = new char[kStackSize + 1];
223171
next_child_stack = new char[kStackSize + 1];
224172
char stack[kStackSize + 1];
173+
// CHECK: WARNING: ASan doesn't fully support makecontext/swapcontext
225174
int ret = 0;
226175
// CHECK-NOT: ASan is ignoring requested __asan_handle_no_return
227176
for (unsigned int i = 0; i < 30; ++i) {

0 commit comments

Comments
 (0)