https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92928
Bug ID: 92928
Summary: When address and UB sanitizer are combined, sanitizing
boost serialization code crashes
Product: gcc
Version: 9.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: sanitizer
Assignee: unassigned at gcc dot gnu.org
Reporter: m4rk0p0p at gmail dot com
CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at
gcc dot gnu.org
Target Milestone: ---
I've tried to use boost serialization to serialize a class which contains a
std::vector<std::unique_ptr<Base>>> as a member (where Base is my abstract base
class). According to the boost documentation
(https://www.boost.org/doc/libs/1_71_0/libs/serialization/doc/serialization.html#derivedpointers),
we must register the derived classes using method register_type of the archive
for the serialization to work properly. However, calling this method results in
abnormal program termination if it is compiled with options -fsanitize=address
-fsanitize=undefined.
The whole example with serialization is too complicated to show here, but I've
analyzed the issue and identified the offending code on lines 188-190 in boost
void_cast
(https://github.com/boostorg/serialization/blob/develop/include/boost/serialization/void_cast.hpp).
In fact, the following program provides a minimal example that reproduces the
issue:
#include <iostream>
class Base
{
public:
virtual ~Base() = default;
virtual bool foo() noexcept = 0;
};
class Derived : public Base
{
public:
Derived() noexcept {};
bool foo() noexcept override { return true; };
};
int main()
{
auto diff = reinterpret_cast<std::ptrdiff_t>(
static_cast<Derived *>(reinterpret_cast<Base *>(1 << 20))) - (1 << 20);
std::cout << diff << "\n";
}
Compiling this code with gcc 9.2 (using -fsanitize=address
-fsanitize=undefined) and running it results in the following output:
ASM generation compiler returned: 0
Execution build compiler returned: 0
Program returned: 255
==3==ERROR: AddressSanitizer failed to allocate 0xdfff0001000 (15392894357504)
bytes at address 2008fff7000 (errno: 12)
==3==ReserveShadowMemoryRange failed while trying to map 0xdfff0001000 bytes.
Perhaps you're using ulimit -v