diff options
| author | Julian Lettner <jlettner@apple.com> | 2019-01-24 01:06:19 +0000 | 
|---|---|---|
| committer | Julian Lettner <jlettner@apple.com> | 2019-01-24 01:06:19 +0000 | 
| commit | cea84ab93aeb079a358ab1c8aeba6d9140ef8b47 (patch) | |
| tree | 3c059cf1dbc208d26fc1df2547d0a18e18448095 /llvm/lib/AsmParser | |
| parent | 970d9d9acc421cc43fa801d2be81328d066200ec (diff) | |
| download | bcm5719-llvm-cea84ab93aeb079a358ab1c8aeba6d9140ef8b47.tar.gz bcm5719-llvm-cea84ab93aeb079a358ab1c8aeba6d9140ef8b47.zip  | |
[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:
  # UBSan now adds the `expect_noreturn` attribute whenever it removes
    the `noreturn` attribute from a function
  # ASan additionally checks for the presence of this attribute
Generated code:
```
call void @__asan_handle_no_return    // Additionally inserted to avoid false positives
call void @longjmp
call void @__asan_handle_no_return
call void @__ubsan_handle_builtin_unreachable
unreachable
```
The second call to `__asan_handle_no_return` is redundant. This will be
cleaned up in a follow-up patch.
rdar://problem/40723397
Reviewers: delcypher, eugenis
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D56624
llvm-svn: 352003
Diffstat (limited to 'llvm/lib/AsmParser')
| -rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 1 | 
3 files changed, 6 insertions, 0 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index b543115a88e..a60639bef0c 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -656,6 +656,7 @@ lltok::Kind LLLexer::LexIdentifier() {    KEYWORD(nonnull);    KEYWORD(noredzone);    KEYWORD(noreturn); +  KEYWORD(expect_noreturn);    KEYWORD(nocf_check);    KEYWORD(nounwind);    KEYWORD(optforfuzzing); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 855c5d26500..9167694607f 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1248,6 +1248,8 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,      case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break;      case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break;      case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break; +    case lltok::kw_expect_noreturn: +      B.addAttribute(Attribute::ExpectNoReturn); break;      case lltok::kw_nocf_check: B.addAttribute(Attribute::NoCfCheck); break;      case lltok::kw_norecurse: B.addAttribute(Attribute::NoRecurse); break;      case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break; @@ -1611,6 +1613,7 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {      case lltok::kw_nonlazybind:      case lltok::kw_noredzone:      case lltok::kw_noreturn: +    case lltok::kw_expect_noreturn:      case lltok::kw_nocf_check:      case lltok::kw_nounwind:      case lltok::kw_optforfuzzing: @@ -1708,6 +1711,7 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {      case lltok::kw_nonlazybind:      case lltok::kw_noredzone:      case lltok::kw_noreturn: +    case lltok::kw_expect_noreturn:      case lltok::kw_nocf_check:      case lltok::kw_nounwind:      case lltok::kw_optforfuzzing: diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index 41899b29ce5..b90394f4c1f 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -200,6 +200,7 @@ enum Kind {    kw_nonnull,    kw_noredzone,    kw_noreturn, +  kw_expect_noreturn,    kw_nocf_check,    kw_nounwind,    kw_optforfuzzing,  | 

