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

Reply via email to