[cfe-dev] stack overflow detection?

Greg Fitzgerald garious at gmail.com
Thu Oct 3 15:00:20 PDT 2013


Have you guys had any luck with the "use_sigaltstack=1" on Android?
I've attempted to use it two versions: the latest clang/compiler-rt
and clang 3.3.  In both cases, the ASan runtime doesn't catch the
stack overflow.  Turning on verbosity=1 reports "tsd_key_inited != 0".
 Here's the full log:

==28386==Parsed ASAN_OPTIONS: use_sigaltstack=1:verbosity=1
==28386==AddressSanitizer: libc interceptors initialized
|| `[0x20000000, 0xffffffff]` || HighMem    ||
|| `[0x04000000, 0x1fffffff]` || HighShadow ||
|| `[0x00040000, 0x03ffffff]` || ShadowGap  ||
MemToShadow(shadow): 0x00000000 0x00000000 0x00800000 0x03ffffff
red_zone=16
quarantine_size=64M
malloc_context_size=30
SHADOW_SCALE: 3
SHADOW_GRANULARITY: 8
SHADOW_OFFSET: 0
==28386==AddressSanitizer CHECK failed:
llvm/projects/compiler-rt/lib/asan/asan_posix.cc:110
"((tsd_key_inited)) != (0)" (0x0, 0x0)
    #0 0x40298bbf in $a _asan_rtl_
    #1 0x4029cb37 in __sanitizer::CheckFailed(char const*, int, char
const*, unsigned long long, unsigned long long) ??:0
    #2 0x40294343 in __asan::AsanTSDGet() ??:0
    #3 0x4029a6f3 in __asan::GetCurrentThread() ??:0
    #4 0x4029a9ab in __asan::GetCurrentTidOrInvalid() ??:0
    #5 0x40293deb in __asan::SetAlternateSignalStack() ??:0
    #6 0x40293f5b in __asan::InstallSignalHandlers() ??:0
    #7 0x402984ff in __asan_init_v3 ??:0


I'm running on Android JellyBean and building with NDK r9.

-Greg


On Wed, Sep 18, 2013 at 10:51 AM, Greg Fitzgerald <garious at gmail.com> wrote:
> Minor correction (environment variable is for the runtime, not compile-time).
>
> was:
> $ ASAN_OPTIONS=use_sigaltstack=1 clang -g -fsanitize=address -o test
> test.c && ./test
>
> should be:
> $ clang -g -fsanitize=address -o test test.c &&
> ASAN_OPTIONS=use_sigaltstack=1 ./test
>
> -Greg
>
> On Wed, Sep 18, 2013 at 10:39 AM, Greg Fitzgerald <garious at gmail.com> wrote:
>> Perfect!  I can confirm this works exactly as described using clang
>> 3.3 running on Ubuntu 12.04 on x86.  Here's what I did:
>>
>> $ export ASAN_SYMBOLIZER_PATH=`which llvm-symbolizer`
>> $ clang --version
>> clang version 3.3 (tags/RELEASE_33/final)
>> Target: x86_64-unknown-linux-gnu
>> Thread model: posix
>>
>> $ cat test.c
>> static void loop() {
>>   loop();
>> }
>>
>> int main() {
>>   loop();
>>   return 0;
>> }
>>
>> $ clang -g -o test test.c && ./test
>> Segmentation fault
>>
>> $ clang -g -fsanitize=address -o test test.c && ./test
>> Segmentation fault
>>
>> $ ASAN_OPTIONS=use_sigaltstack=1 clang -g -fsanitize=address -o test
>> test.c && ./test
>>
>> ==12279==ERROR: AddressSanitizer: SEGV on unknown address
>> 0x7fffb5066960 (pc 0x00000042d4a7 sp 0x7fffb5066940 bp 0x7fffb5067970
>> T0)
>> AddressSanitizer can not provide additional info.
>>     #0 0x42d4a6 in loop test.c:1
>>     #1 0x42d4db in loop test.c:3
>>     #2 0x42d4db in loop test.c:3
>>     #3 0x42d4db in loop test.c:3
>>     ...
>>
>> I agree that this option should be enabled by default.  This is useful stuff!
>>
>> -Greg
>>
>> On Wed, Sep 18, 2013 at 1:19 AM, Kostya Serebryany <kcc at google.com> wrote:
>>>
>>>
>>>
>>> On Wed, Sep 18, 2013 at 2:18 AM, Greg Fitzgerald <garious at gmail.com> wrote:
>>>>
>>>> Thanks for the quick replies!
>>>>
>>>>
>>>> > If you want dynamic detection, then Address Sanitizer (which is built
>>>> > into Clang) or SAFECode
>>>>
>>>> Dynamic detection.  I tried with Address Sanitizer and no luck
>>>
>>>
>>> AddressSanitizer does not try to detect stack overflow (not to be mixed with
>>> stack-buffer-overflow).
>>> The reason is simple: when stack overflow happens it is already detected
>>> (you get a SEGV).
>>> However, by default when stack overflow happens the SEGV kills the process
>>> silently because
>>> the signal handler has no stack to run on.
>>> This can be solved with sigaltstack() and AddressSanitizer does this under a
>>> separate
>>> (experimental) flag ASAN_OPTIONS=use_sigaltstack=1
>>>
>>> # Running with default 8Mb stack
>>> % clang -g -fsanitize=address -O
>>> ~/llvm/projects/compiler-rt/lib/asan/lit_tests/TestCases/deep_call_stack.cc
>>> ; ./a.out
>>> [40000] ptr: (nil)
>>> ...
>>> [00000] ptr: 0x7fff0b7c4140
>>> # Passed
>>>
>>> # Running with a small stack
>>> % (ulimit -s 1000; ./a.out; echo $?  )
>>> [40000] ptr: (nil)
>>> ...
>>> [33000] ptr: 0x7fff0e155120
>>> 139  # FAILED
>>>
>>> # Running with a small stack and with sigaltstack
>>> % (ulimit -s 1000; ASAN_OPTIONS=use_sigaltstack=1 ./a.out; echo $?  ) 2>&1 |
>>> head
>>> ASAN:SIGSEGV
>>> =================================================================
>>> ==1543==ERROR: AddressSanitizer: SEGV on unknown address 0x7fffa383bfe0 (pc
>>> 0x000000456d38 sp 0x7fffa383bfe0 bp 0x7fffa383c050 T0)
>>> AddressSanitizer can not provide additional info.
>>>     #0 0x456d37 in RecursiveFunc(int, int*)
>>> /home/kcc/llvm/projects/compiler-rt/lib/asan/lit_tests/TestCases/deep_call_stack.cc:8
>>>     #1 0x456dbc in RecursiveFunc(int, int*)
>>> /home/kcc/llvm/projects/compiler-rt/lib/asan/lit_tests/TestCases/deep_call_stack.cc:14
>>>
>>>
>>> hth,
>>>
>>> --kcc
>>>
>>>
>>>
>>>> out-of-the-box.  I think it can detect stack-buffer-overflow (aka
>>>> stack corruption), but not stack overflow.  I also tried running the
>>>> code with ASan inside a pthread with heap-allocated memory for its
>>>> stack, but since the pthread library itself is not instrumented, it
>>>> did not detect the heap-buffer-overflow when the thread's stack
>>>> overflows.
>>>>
>>>>
>>>> > or SAFECode
>>>>
>>>> Can you point me to an example?
>>>>
>>>>
>>>> Eli Friedman wrote:
>>>> > No such support exists at the moment.
>>>>
>>>> Is anyone aware of another C compiler that adds instrumentation for
>>>> stack overflow detection?
>>>>
>>>> Thanks,
>>>> Greg
>>>>
>>>> On Tue, Sep 17, 2013 at 3:03 PM, John Criswell <criswell at illinois.edu>
>>>> wrote:
>>>> > On 9/17/13 4:57 PM, Greg Fitzgerald wrote:
>>>> >>
>>>> >> Does clang offer any tools for detecting when a program is about to
>>>> >> segfault due to stack overflow?
>>>> >
>>>> >
>>>> > If you want dynamic detection, then Address Sanitizer (which is built
>>>> > into
>>>> > Clang) or SAFECode (which has its own version of Clang into which it is
>>>> > integrated) will do the trick.
>>>> >
>>>> > If you're asking about the Clang static analyzer, then I do not know.
>>>> >
>>>> > -- John T.
>>>> >
>>>> >>
>>>> >> Thanks,
>>>> >> Greg
>>>> >> _______________________________________________
>>>> >> cfe-dev mailing list
>>>> >> cfe-dev at cs.uiuc.edu
>>>> >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>>>> >
>>>> >
>>>> _______________________________________________
>>>> cfe-dev mailing list
>>>> cfe-dev at cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>>>
>>>



More information about the cfe-dev mailing list