Using ASAN suppressions in mixed-instrumented environments

I’ve got an application I built with -fsanitize=address, and I’m linking against a third party library foo.a which was not built with -fsanitize=address. Both of these libraries use -stdlib=libc++.

In my code I do something like this:

// This code is instrumented
void MyProgram() {

std::vectorstd::string v;
std::string s;
Library::DoSomethingUseful(v, s);
}

And this is implemented as:

// This code is not instrumented:
namespace Library {
void DoSomethingUseful(std::vectorstd::string &v, const std::string &s) {
for (int i=0; i < 10; ++i)
v.push_back(s);
}
}

This results in an ASAN container-overflow in libc++, which makes sense because the library’s version isn’t instrumented. Is there any way to suppress this?

The actual call-stack looks like this:

==120108==ERROR: AddressSanitizer: container-overflow on address 0x60800002e4e8 at pc 0x562899512022 bp 0x7ffc0ad94d10 sp 0x7ffc0ad944c0
READ of size 24 at 0x60800002e4e8 thread T0
#0 0x562899512021 in __asan_memcpy (MyProgram+0x22c7021)
#1 0x562899609a51 in std::string::basic_string(std::string&&) /usr/include/c++/v1/string:1683:7
#2 0x562899609a51 in void std::allocatorstd::string::construct<std::string, std::string >(std::string*, std::string&&) /usr/include/c++/v1/memory:1805
#3 0x562899609a51 in void std::allocator_traits<std::allocatorstd::string >::__construct<std::string, std::string >(std::__1::integral_constant<bool, true>, std::allocatorstd::string&, std::string*, std::string&&) /usr/include/c++/v1/memory:1715
#4 0x562899609a51 in void std::allocator_traits<std::allocatorstd::string >::construct<std::string, std::string >(std::allocatorstd::string&, std::string*, std::string&&) /usr/include/c++/v1/memory:1561
#5 0x562899609a51 in void std::allocator_traits<std::allocatorstd::string >::__construct_backwardstd::string*(std::allocatorstd::string&, std::string*, std::string*, std::string*&) /usr/include/c++/v1/memory:1677
#6 0x562899609a51 in std::__1::vector<std::string, std::allocatorstd::string >::__swap_out_circular_buffer(std::__1::__split_buffer<std::string, std::allocatorstd::string&>&) /usr/include/c++/v1/vector:898
#7 0x562899608928 in void std::__1::vector<std::string, std::allocatorstd::string >::__push_back_slow_path<std::string const&>(std::string const&) /usr/include/c++/v1/vector:1582:5
#8 0x56289f792aa9 in std::__1::vector<std::string, std::allocatorstd::string >::push_back(std::string const&) /usr/include/c++/v1/vector:1599:9
#9 0x56289f792aa9 in MyLibrary::DoSomethingUseful(std::vectorstd::string&, std::string const&)

It’s not reasonable for me to suppress everything that might happen in libc++, because I might have an actual violation which occurs from instrumented code.

I can disable container-overflow but that seems suboptimal too.

Is there a good workaround for this situation? Ideally I’d like to use an LSAN-style suppression that allows me to match anywhere in the callstack, but this doesn’t appear to be supported.

Advice appreciated.