Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

AddressSanitizerUseAfterReturn

Ragh Srinivasan edited this pageDec 19, 2022 ·5 revisions

Introduction

Stack-use-after-return bug appears when a stack object is used afterthe function where this object is defined has returned.Example (see alsoAddressSanitizerExampleUseAfterReturn):

int *ptr;void FunctionThatEscapesLocalObject() {  int local[100];  ptr = &local[0];}// *ptr is used later

AddressSanitizer currently does not attempt to detect these bugs by default,only with an additional flag run-time: ASAN_OPTIONS=detect_stack_use_after_return=1

Algorithm

Detection of stack-use-after-return is similar to detection of heap-use-after-free,but thequarantine should be implemented in a different way.

Once a function has returned, its stack memory is reused by the next call instruction.So in order to implement quarantine for the stack memory we need to promote stack to heap.The current implementation does it like this:

Before:

void foo() {  int local;  escape_addr(&local);}

After:

void foo() {  char redzone1[32];  int local;  char redzone2[32+28];  char *fake_stack = __asan_stack_malloc(&local, 96);  poison_redzones(fake_stack);  // Done by the inlined instrumentation code.  escape_addr(fake_stack + 32);  __asan_stack_free(stack, &local, 96)}

__asan_stack_malloc(real_stack, frame_size) allocates afake frame(frame_size bytes) from a thread-local heap-like structure (fake stack).Every fake frame comes unpoisoned and then the redzones are poisoned in the instrumentedfunction code.

__asan_stack_free(fake_stack, real_stack, frame_size)poisons the entire fake frame and deallocates it.

Memory consumption

TheFake Stack allocator uses a fixed amount of memory per each thread.The allocator has 11 size classes (from2**6 bytes to2**16 bytes),every size class has fixed amount of chunks.If the given size class is fully used, the allocator will return 0 and thus regular stack will be used(i.e. stack-use-after-return detection will not work for the given function call).The amount of memory given to every size class is proportional to the size of thread's real stack,but not more than2**max_uar_stack_size_log (by default,2**20)and not less than2**min_uar_stack_size_log (by default,2**16). See also:AddressSanitizerFlags.

So, with the default 8Mb stack size and defaultAddressSanitizerFlags each size class will get2**20 bytes and thus every thread will mmap ~11Mb for Fake Stack.

The bigger the Fake Stack the better your chances to catch a stack-use-after-return and get a correct report, but the greater is the memory consumption.

Performance

Detecting stack-use-after-return is expensive in both CPU and RAM:

  • Allocating fake frames introduces two function calls per every function with non-empty frame.
  • The entire fake frames should be unpoisoned on entry and poisoned on exit, as opposed to poisoning just the redzones in the default mode.

These are the performance numbers on SPEC 2006. We've compared pure asan against ASAN_OPTIONS=detect_stack_use_after_return=1 both with-fsanitize=address -O2.4 benchmarks get 30% extra slowdown and one gets almost 2x extra slowdown. Other 14 benchmarks are not affected at all.

400.perlbench1269.001653.001.30
401.bzip2845.00847.001.00
403.gcc611.00629.001.03
429.mcf582.00581.001.00
445.gobmk841.001093.001.30
456.hmmer902.00924.001.02
458.sjeng996.001244.001.25
462.libquantum541.00511.000.94
464.h264ref1266.001288.001.02
471.omnetpp567.00564.000.99
473.astar636.00642.001.01
483.xalancbmk465.00595.001.28
433.milc651.00652.001.00
444.namd599.00597.001.00
447.dealII616.00610.000.99
450.soplex358.00363.001.01
453.povray432.00821.001.90
470.lbm384.00378.000.98
482.sphinx3930.00927.001.00

Garbage collection

We have an experimental API to support interoperability ofAddressSanitizer's fake stack with garbage collection.Seehttp://llvm.org/viewvc/llvm-project?view=revision&revision=200908 and stay tuned for more news.

Compatibility

The fake stack may be incompatible with some low-level code thatuses certain assumptions about the stack memory layout.

  • Code that takes an address of a local variable and assumes the variable is localed on the real stack.
  • Implementations of C++ garbage collection may require special attention. See above.

TODO

Clone this wiki locally


[8]ページ先頭

©2009-2026 Movatter.jp