I'm trying to get control flow integrity to work with clang++ but I can't get the following code to run:
#include <memory>
struct X {
X() {}
virtual ~X() {};
};
int main() {
std::shared_ptr<X> _asd = std::make_shared<X>();
return 0;
}
If I compile and run this with
clang++ -fsanitize=cfi -fvisibility=hidden -flto -O2 -std=c++14 test.cpp
./a.out
the compiled program outputs:
[1] 45850 illegal hardware instruction (core dumped) ./a.out
The resulting program crashes inside the make_shared function call - inside the standard library.
Some observations
When I make the destructor non-virtual it terminates successfully, so I initially thought it had something to do with cfi-vcall but it works flawlessly with the -fsanitize=cfi-vcall option.
The responsible compile flag seems to be -fsanitize=cfi-unrelated-cast - with all other available checks the application runs properly.
Looking at the disassembly it seems that the application is calling ~X() within make_shared (see also Additional Info below)?
Questions
Is this a programming mistake? Is it in the compiler, standard library or in my code?
Is there a workaround to make it compile and run with CFI enabled?
Thanks a lot in advance!
Additional Info
here's the context (gef) one instruction before the invalid ud1 instruction.
[rbx+0x10] that rax is compared to is just zeros:
gef➤ x/1g $rbx + 0x10
0x557ec94ffec0: 0x0000000000000000


