]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
boot: Add undefined sanitizer support 26759/head
authorJan Janssen <medhefgo@web.de>
Sun, 12 Mar 2023 15:51:48 +0000 (16:51 +0100)
committerJan Janssen <medhefgo@web.de>
Fri, 17 Mar 2023 09:39:39 +0000 (10:39 +0100)
Sadly, no stack traces, but this is better than nothing.

src/boot/efi/log.c
src/boot/efi/log.h
src/boot/efi/meson.build
src/boot/efi/ubsan.c [new file with mode: 0644]

index 82307516dcfa9aa6d1e2f495db3cbe1a44514909..6d0edec2cfac2fb10ee4192bf72a2ea31ffe2a72 100644 (file)
@@ -6,7 +6,7 @@
 
 static unsigned log_count = 0;
 
-_noreturn_ static void freeze(void) {
+void freeze(void) {
         for (;;)
                 BS->Stall(60 * 1000 * 1000);
 }
index 7b2735d028f4e391fe719c67456866a6fa4281c6..973e13c260ad704d0c41af041a753a067f3a38b8 100644 (file)
@@ -19,6 +19,7 @@ __attribute__((no_stack_protector, noinline)) void __stack_chk_guard_init(void);
 #  define __stack_chk_guard_init()
 #endif
 
+_noreturn_ void freeze(void);
 void log_wait(void);
 _gnu_printf_(2, 3) EFI_STATUS log_internal(EFI_STATUS status, const char *format, ...);
 #define log_error_status(status, ...) log_internal(status, __VA_ARGS__)
index 58bebe446e66c7fc4bb269d1304406f16115866b..e6e7eed3bcac6a8f661c386428862e41cba3014d 100644 (file)
@@ -179,17 +179,23 @@ efi_disabled_c_args = cc.get_supported_arguments(
         '-fcf-protection=none',
         '-fno-asynchronous-unwind-tables',
         '-fno-exceptions',
-        '-fno-sanitize=all',
         '-fno-unwind-tables',
 )
-efi_c_args += efi_disabled_c_args
-efi_c_ld_args += efi_disabled_c_args
 efi_override_options = [
         'b_coverage=false',
         'b_pgo=off',
-        'b_sanitize=none',
 ]
 
+if get_option('b_sanitize') == 'undefined'
+        efi_disabled_c_args += cc.get_supported_arguments('-fno-sanitize-link-runtime')
+else
+        efi_disabled_c_args += cc.get_supported_arguments('-fno-sanitize=all')
+        efi_override_options += 'b_sanitize=none'
+endif
+
+efi_c_args += efi_disabled_c_args
+efi_c_ld_args += efi_disabled_c_args
+
 if cc.get_id() == 'clang'
         # clang is too picky sometimes.
         efi_c_args += '-Wno-unused-command-line-argument'
@@ -252,6 +258,10 @@ stub_sources = files(
         'stub.c',
 )
 
+if get_option('b_sanitize') == 'undefined'
+        libefi_sources += files('ubsan.c')
+endif
+
 if host_machine.cpu_family() in ['x86', 'x86_64']
         stub_sources += files('linux_x86.c')
 endif
diff --git a/src/boot/efi/ubsan.c b/src/boot/efi/ubsan.c
new file mode 100644 (file)
index 0000000..9512046
--- /dev/null
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "log.h"
+
+typedef struct {
+        const char *filename;
+        uint32_t line;
+        uint32_t column;
+} SourceLocation;
+
+/* Note that all ubsan handlers have a pointer to a type-specific struct passed as first argument.
+ * Since we do not inspect the extra data in it we can just treat it as a SourceLocation struct
+ * directly to keep things simple. */
+
+#define HANDLER(name, ...)                                         \
+        _used_ _noreturn_ void __ubsan_handle_##name(__VA_ARGS__); \
+        void __ubsan_handle_##name(__VA_ARGS__) {                  \
+                log_error("systemd-boot: %s in %s@%u:%u",          \
+                          __func__,                                \
+                          location->filename,                      \
+                          location->line,                          \
+                          location->column);                       \
+                freeze();                                          \
+        }
+
+#define UNARY_HANDLER(name) HANDLER(name, SourceLocation *location, uintptr_t v)
+#define BINARY_HANDLER(name) HANDLER(name, SourceLocation *location, uintptr_t v1, uintptr_t v2)
+
+UNARY_HANDLER(load_invalid_value);
+UNARY_HANDLER(negate_overflow);
+UNARY_HANDLER(out_of_bounds);
+UNARY_HANDLER(type_mismatch_v1);
+UNARY_HANDLER(vla_bound_not_positive);
+
+BINARY_HANDLER(add_overflow);
+BINARY_HANDLER(divrem_overflow);
+BINARY_HANDLER(implicit_conversion);
+BINARY_HANDLER(mul_overflow);
+BINARY_HANDLER(pointer_overflow);
+BINARY_HANDLER(shift_out_of_bounds);
+BINARY_HANDLER(sub_overflow);
+
+HANDLER(builtin_unreachable, SourceLocation *location);
+HANDLER(invalid_builtin, SourceLocation *location);
+HANDLER(nonnull_arg, SourceLocation *location);
+HANDLER(nonnull_return_v1, SourceLocation *attr_location, SourceLocation *location);