diff options
author | Jan Janssen <medhefgo@web.de> | 2023-03-12 16:51:48 +0100 |
---|---|---|
committer | Jan Janssen <medhefgo@web.de> | 2023-03-17 10:39:39 +0100 |
commit | 1e7ff4ba8855996c8e077e0546acf9491c97663f (patch) | |
tree | c2e50735d33324c8d2ab971f1fad1a49013dc144 /src/boot | |
parent | meson: Share more C flags (diff) | |
download | systemd-1e7ff4ba8855996c8e077e0546acf9491c97663f.tar.xz systemd-1e7ff4ba8855996c8e077e0546acf9491c97663f.zip |
boot: Add undefined sanitizer support
Sadly, no stack traces, but this is better than nothing.
Diffstat (limited to 'src/boot')
-rw-r--r-- | src/boot/efi/log.c | 2 | ||||
-rw-r--r-- | src/boot/efi/log.h | 1 | ||||
-rw-r--r-- | src/boot/efi/meson.build | 18 | ||||
-rw-r--r-- | src/boot/efi/ubsan.c | 46 |
4 files changed, 62 insertions, 5 deletions
diff --git a/src/boot/efi/log.c b/src/boot/efi/log.c index 82307516dc..6d0edec2cf 100644 --- a/src/boot/efi/log.c +++ b/src/boot/efi/log.c @@ -6,7 +6,7 @@ static unsigned log_count = 0; -_noreturn_ static void freeze(void) { +void freeze(void) { for (;;) BS->Stall(60 * 1000 * 1000); } diff --git a/src/boot/efi/log.h b/src/boot/efi/log.h index 7b2735d028..973e13c260 100644 --- a/src/boot/efi/log.h +++ b/src/boot/efi/log.h @@ -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__) diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 58bebe446e..e6e7eed3bc 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -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 index 0000000000..951204683e --- /dev/null +++ b/src/boot/efi/ubsan.c @@ -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); |