[Sanitizers] UBSan unreachable incompatible with ASan in the presence of `noreturn...
authorJulian Lettner <jlettner@apple.com>
Fri, 1 Feb 2019 02:51:00 +0000 (02:51 +0000)
committerJulian Lettner <jlettner@apple.com>
Fri, 1 Feb 2019 02:51:00 +0000 (02:51 +0000)
commitb6c06dc28f96032d5bf101ed8e61549442dc912d
tree5a16d6d1270d4447b3afcc681cc0d70fb17b8466
parent7cc0753118473b5a1c646b826819b294a55c302e
[Sanitizers] UBSan unreachable incompatible with ASan in the presence of `noreturn` calls

Summary:
UBSan wants to detect when unreachable code is actually reached, so it
adds instrumentation before every unreachable instruction. However, the
optimizer will remove code after calls to functions marked with
noreturn. To avoid this UBSan removes noreturn from both the call
instruction as well as from the function itself. Unfortunately, ASan
relies on this annotation to unpoison the stack by inserting calls to
_asan_handle_no_return before noreturn functions. This is important for
functions that do not return but access the the stack memory, e.g.,
unwinder functions *like* longjmp (longjmp itself is actually
"double-proofed" via its interceptor). The result is that when ASan and
UBSan are combined, the noreturn attributes are missing and ASan cannot
unpoison the stack, so it has false positives when stack unwinding is
used.

Changes:
Clang-CodeGen now directly insert calls to `__asan_handle_no_return`
when a call to a noreturn function is encountered and both
UBsan-unreachable and ASan are enabled. This allows UBSan to continue
removing the noreturn attribute from functions without any changes to
the ASan pass.

Previously generated code:
```
  call void @longjmp
  call void @__asan_handle_no_return
  call void @__ubsan_handle_builtin_unreachable
```

Generated code (for now):
```
  call void @__asan_handle_no_return
  call void @longjmp
  call void @__asan_handle_no_return
  call void @__ubsan_handle_builtin_unreachable
```

rdar://problem/40723397

Reviewers: delcypher, eugenis, vsk

Differential Revision: https://reviews.llvm.org/D57278

> llvm-svn: 352690

llvm-svn: 352829
clang/lib/CodeGen/CGCall.cpp
clang/lib/CodeGen/CodeGenFunction.h
clang/test/CodeGen/ubsan-asan-noreturn.c [new file with mode: 0644]
clang/test/CodeGenCXX/ubsan-unreachable.cpp