Search code examples
c++indexoutofboundsexceptionsanitization

Undefined sanitization unable to detect a simple stack out-of-bound error


#include <iostream>
void fill(int *);

int main() {
    int a[1];
    int b[1];
    a[0] = 1;
    b[0] = 2;
    fill(a);

    std::cout << *a << " " << *b << std::endl;
}

void fill (int * x) {
    x[1] = 3;
}

This code produces an out-of-bound situation, where the stack-value b[0] is overwritten by fill(a).

The code has been compiled using

g++ main.cpp -fsanitize=undefined -lstdc++ -lubsan

however the sanitizer is unable to detect the error.

Am I missing something?


Solution

  • Am I missing something?

    Yes. Stack overflows are detected by the address santizer, not the UB santizer. Compiling your snippet with -fsanitize=address gives

    =17847==ERROR: AddressSanitizer: stack-buffer-overflow on address ... at pc ...
    
    #0 0x10f7f5d44 in fill(int*) (a.out:x86_64+0x100000d44)
    #1 0x10f7f5b81 in main (a.out:x86_64+0x100000b81)
    #2 0x7fff5f490014 in start (libdyld.dylib:x86_64+0x1014)
    
    ...
    

    Technically, an out of bounds access on the stack does lead to undefined behavior. But putting everything that leads to UB into the UB sanitizer is probably too little separation of concerns. From the clang address sanitizer docs:

    AddressSanitizer is a fast memory error detector. It consists of a compiler instrumentation module and a run-time library. The tool can detect the following types of bugs:

    • Out-of-bounds accesses to heap, stack and globals
    • ...

    while the list of checks that the UB sanitizer implements can be found here (again, clang docs).