[llvm-bugs] [Bug 35431] New: CFI (Control Flow Integrity) emits invalid checks when using std::make_shared (C++11)
via llvm-bugs
llvm-bugs at lists.llvm.org
Mon Nov 27 04:20:50 PST 2017
https://bugs.llvm.org/show_bug.cgi?id=35431
Bug ID: 35431
Summary: CFI (Control Flow Integrity) emits invalid checks when
using std::make_shared (C++11)
Product: clang
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: -New Bugs
Assignee: unassignedclangbugs at nondot.org
Reporter: adrien at guinet.me
CC: llvm-bugs at lists.llvm.org
Created attachment 19477
--> https://bugs.llvm.org/attachment.cgi?id=19477&action=edit
test case
Hello all,
CFI (Control Flow Integrity) generates bad code when std::make_shared is used
for C++11 code. The bad code involve a comparaison which will always fail, and
jump to the "ud2" instruction (on X86), as if an invalid call (in the CFI
sense) would have been made.
Using the joint a.cpp file, one can reproduce this using current LLVM trunk
(r319014). The bug happens using GNU's libstdc++, with full or thin lto:
$ build/bin/clang++ -fsanitize=cfi -fvisibility=hidden -flto=full -O2 a.cpp
-fPIC -o a_full -std=c++11 && ./a_full
Illegal instruction
$ build/bin/clang++ -fsanitize=cfi -fvisibility=hidden -flto=thin -O2 a.cpp
-fPIC -o a_thin -std=c++11 && ./a_thin
Illegal instruction
If we take a look at the assembly generated in both cases, it looks like this:
- for a_full:
400850 new_ptr2(void) proc near
400850 push rbx
400851 mov rbx, rdi
400854 mov edi, 28h
400859 call operator new(ulong)
40085E mov rcx, 100000001h
400868 mov [rax+8], rcx
40086C mov qword ptr [rax], offset off_400C80
400873 mov ecx, offset off_400CC0
400878 cmp [rax+10h], rcx <-- memory at rax+0x10 has never been
initialized, this equality is always false!
40087C jnz short loc_40089D
40087E mov rcx, rax
400881 add rcx, 10h
400885 xorps xmm0, xmm0
400888 movups xmmword ptr [rax+18h], xmm0
40088C mov qword ptr [rax+10h], offset off_400CC0
400894 mov [rbx], rcx
400897 mov [rbx+8], rax
40089B pop rbx
40089C retn
- for a_thin:
400850 new_ptr2(void) proc near
400850 push rbx
400851 mov rbx, rdi
400854 mov edi, 28h
400859 call operator new(ulong)
40085E mov rcx, 100000001h
400868 mov [rax+8], rcx
40086C mov qword ptr [rax], offset
__typeid__ZTSSt23_Sp_counted_ptr_inplaceI2S2SaIS0_ELN9__gnu_cxx12_Lock_policyE2EE_global_addr400873
mov ecx, offset
__typeid__ZTSSt23_Sp_counted_ptr_inplaceI2S2SaIS0_ELN9__gnu_cxx12_Lock_policyE2EE_global_addr
400878 mov edx, offset
__typeid__ZTSSt23_Sp_counted_ptr_inplaceI2S2SaIS0_ELN9__gnu_cxx12_Lock_policyE2EE_global_addr
40087D cmp rdx, rcx
400880 jnz short loc_4008BE
400882 mov ecx, offset __typeid__ZTS4Base_global_addr
400887 cmp [rax+10h], rcx <-- same here, memory at rax+0x10 has never
been initialized, this equality is always false!
40088B jnz short loc_4008BE
40088D xorps xmm0, xmm0
400890 movups xmmword ptr [rax+18h], xmm0
400894 mov qword ptr [rax+10h], offset __typeid__ZTS4Base_global_addr
40089C mov ecx, offset __typeid__ZTS4Base_global_addr
4008A1 mov edx, offset __typeid__ZTS4Base_global_addr
4008A6 cmp rdx, rcx
4008A9 jnz short loc_4008BE
4008AB mov rcx, rax
4008AE add rcx, 10h
4008B2 mov [rbx], rcx
4008B5 mov [rbx+8], rax
4008B9 mov rax, rbx
4008BC pop rbx
4008BD retn
For the record, this does not happen using LLVM's libc++:
$ build/bin/clang++ -fsanitize=cfi -fvisibility=hidden -flto=full -O2 a.cpp
-fPIC -o a -std=c++11 -stdlib=libc++ && ./a
S2
$ build/bin/clang++ -fsanitize=cfi -fvisibility=hidden -flto=thin -O2 a.cpp
-fPIC -o a -std=c++11 -stdlib=libc++ && ./a
S2
Question is to know whether this is due to some bug in libstdc++ or a bug in
CFI. Note that using the official LLVM 5 release, the bug happens for both C++
libraries, which might point to an actual CFI bug.
For the record, this bug has been found while building Clang/LLVM using clang
with CFI. This kind of construction (using std::make_shared) exists for
instance in clang's RealFileSystem::dir_begin function (in
clang/lib/Basic/VirtualFileSystem.cpp).
Please let me know if you need further information.
Regards,
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20171127/a502dd90/attachment.html>
More information about the llvm-bugs
mailing list