getsoubl
getsoubl

Reputation: 1055

C++ Use Container annotation wrapper for detect memory buffer overflow does not work

I am trying to use Container annotation wrappers for force ASan to detect buffer overflow for a pointer which allocates memory from the stack. Below is my example

#include <sanitizer/asan_interface.h>
#include <iostream>
#include <array>

constexpr size_t N = 32;

class A {
public:
    int x;
};

int main() {
    char buf [sizeof(A)];
    A *a = new (buf) A;
    __sanitizer_annotate_contiguous_container(buf, buf + sizeof(A), buf, buf + sizeof(A));
    a->~A();
    a[sizeof(A) + 64].x = 4;
    std::cout << a[sizeof(A) + 64].x << std::endl;
}

Why sanitizer does not detect the memory violation?

demo

Upvotes: 0

Views: 80

Answers (1)

Kirisame Igna
Kirisame Igna

Reputation: 401

First, it seems like you used __sanitizer_annotate_contiguous_container wrongly. Its signature is:

void __sanitizer_annotate_contiguous_container(const void *beg_p,
                                               const void *end_p,
                                               const void *old_mid_p,
                                               const void *new_mid_p)

So when you're releasing a, you would like to mark it as

__sanitizer_annotate_contiguous_container(buf, buf + sizeof(A), buf + sizeof(A), buf);

Second, it seems like the reason that ASAN doesn't report the overflow on stack is that ASAN only marks 3 shadow bytes (24 actual bytes) past the frame boundary as non-addressable, which can be find out quite easily by looking at the shadow bytes on error:

shadow memory layout

https://godbolt.org/z/Mxz7qxhfo

Here, you're addressing the stack at (sizeof(A) + 64) * sizeof(A) = 272 bytes past the frame start, or 264 bytes past the frame end, thus no error is thrown. If you allocate buf on the heap, as ASAN marks a much wider redzone on heap allocation, you'll find the memory violation correctly reported, but the reason would be "heap overflow", not "container overflow".

Upvotes: 0

Related Questions