- Notifications
You must be signed in to change notification settings - Fork1.1k
AddressSanitizerContainerOverflow
One kind of bugs thatAddressSanitizer can find with the help of code annotations is, as we call it, "container-overflow". Givenstd::vector<T> v a container-overflow is a memory access inside the range[v.end(), v.begin() + v.capacity()), i.e. inside the allocated heap region but outside of the current container bounds.
Simplest example:
#include <vector>#include <assert.h>typedef long T;int main() { std::vector<T> v; v.push_back(0); v.push_back(1); v.push_back(2); assert(v.capacity() >= 4); assert(v.size() == 3); T *p = &v[0]; // Here the memory is accessed inside a heap-allocated buffer // but outside of the region `[v.begin(), v.end())`. return p[3]; // OOPS. // v[3] could be detected by simple checks in std::vector. // *(v.begin()+3) could be detected by a mighty debug iterator // (&v[0])[3] can only be detected with AddressSanitizer or similar.}std::vector is annotated in LLVM's libc++ as ofr208319.(See alsothe discussion).We are also working on annotations for libstdc++:first step.Next steps are to annotatestd::string andstd::deque.
Another side effect of container annotations will be improved sensitivity of LeakSanitizer.In the following example we have a leak because a pointer is removed from a global vector usingpop_back,but w/o the annotations LeakSanitizer will treat the pointer as live because it still remains inside the vector's storage.
#include <vector>std::vector<int *> *v;int main(int argc, char **argv) { v = new std::vector<int *>; v->push_back(new int [10]); v->push_back(new int [20]); v->push_back(new int [30]); v->push_back(new int [40]); v->pop_back(); // The last element leaks now.}We know about at least one kind of false positive container overflow reports.If a part of the application is built with asan and another part is not instrumented,and both parts use e.g. instrumentedstd::vector, asan may report non-existent container overflow.This happens because instrumented and non-instrumented bits ofstd::vector, inlined and not, are mixed during linking, so you end up with incompletely instrumentedstd::vector.
Solution: either build the entire application with asan or disable container overflow detection (ASAN_OPTIONS=detect_container_overflow=0)