Sfoglia il codice sorgente

LibSanitizer: Abort on unrecoverable UBSan errors

There is no sensible recovery possible from non-void functions that
fail to return a value, or from `__builtin_unreachable()` being reached,
all bets are off once they happened. This is why LLVM's libsanitizer
treats these as always fatal, even if all other UBSan checks are made
recoverable with `-fsanitize-recover`. The codegen already assumes that
these handlers will not return.
Daniel Bertalan 2 anni fa
parent
commit
a2d352c4c9
1 ha cambiato i file con 16 aggiunte e 12 eliminazioni
  1. 16 12
      Userland/Libraries/LibSanitizer/UBSanitizer.cpp

+ 16 - 12
Userland/Libraries/LibSanitizer/UBSanitizer.cpp

@@ -15,6 +15,12 @@ Atomic<bool> AK::UBSanitizer::g_ubsan_is_deadly;
     warnln(fmt, ##__VA_ARGS__);    \
     dbgln("\x1B[31m" fmt "\x1B[0m", ##__VA_ARGS__);
 
+#define ABORT_ALWAYS()                                            \
+    do {                                                          \
+        WARNLN_AND_DBGLN("UBSAN: This error is not recoverable"); \
+        abort();                                                  \
+    } while (0)
+
 extern "C" {
 
 static void print_location(SourceLocation const& location)
@@ -47,6 +53,10 @@ static void print_location(SourceLocation const& location)
     }
 }
 
+// Calls to these functions are automatically inserted by the compiler,
+// so there is no point in declaring them in a header.
+#pragma GCC diagnostic ignored "-Wmissing-declarations"
+
 void __ubsan_handle_load_invalid_value(InvalidValueData&, ValueHandle) __attribute__((used));
 void __ubsan_handle_load_invalid_value(InvalidValueData& data, ValueHandle)
 {
@@ -233,24 +243,18 @@ void __ubsan_handle_alignment_assumption(AlignmentAssumptionData& data, ValueHan
     print_location(location);
 }
 
-void __ubsan_handle_builtin_unreachable(UnreachableData&) __attribute__((used));
-void __ubsan_handle_builtin_unreachable(UnreachableData& data)
+[[gnu::used, noreturn]] void __ubsan_handle_builtin_unreachable(UnreachableData& data)
 {
-    auto location = data.location.permanently_clear();
-    if (!location.needs_logging())
-        return;
     WARNLN_AND_DBGLN("UBSAN: execution reached an unreachable program point");
-    print_location(location);
+    print_location(data.location);
+    ABORT_ALWAYS();
 }
 
-void __ubsan_handle_missing_return(UnreachableData&) __attribute__((used));
-void __ubsan_handle_missing_return(UnreachableData& data)
+[[gnu::used, noreturn]] void __ubsan_handle_missing_return(UnreachableData& data)
 {
-    auto location = data.location.permanently_clear();
-    if (!location.needs_logging())
-        return;
     WARNLN_AND_DBGLN("UBSAN: execution reached the end of a value-returning function without returning a value");
-    print_location(location);
+    print_location(data.location);
+    ABORT_ALWAYS();
 }
 
 void __ubsan_handle_implicit_conversion(ImplicitConversionData&, ValueHandle, ValueHandle) __attribute__((used));