From 450b9160fdcdb0b770b316caf1d72ab893bc7aa5 Mon Sep 17 00:00:00 2001 From: Aleksa Vuckovic Date: Sun, 27 Nov 2022 19:25:27 +0100 Subject: panic & ssp --- kernel/Makefile | 4 +- kernel/include/panic.h | 6 + kernel/src/check/panic.c | 12 ++ kernel/src/check/ssp.c | 14 ++ kernel/src/check/ubsan.c | 386 ++++++++++++++++++++++++++++++++++++++++++++++ kernel/src/cpu/irq.c | 31 ++++ kernel/src/ubsan/ubsan.c | 388 ----------------------------------------------- 7 files changed, 452 insertions(+), 389 deletions(-) create mode 100644 kernel/include/panic.h create mode 100644 kernel/src/check/panic.c create mode 100644 kernel/src/check/ssp.c create mode 100644 kernel/src/check/ubsan.c delete mode 100644 kernel/src/ubsan/ubsan.c (limited to 'kernel') diff --git a/kernel/Makefile b/kernel/Makefile index a8fd434..bf5b008 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -5,6 +5,9 @@ OBJS = \ src/boot/boot.o \ src/boot/header.o \ src/boot/multiboot2.o \ + src/check/panic.o \ + src/check/ssp.o \ + src/check/ubsan.o \ src/cpu/gdt.o \ src/cpu/idt.o \ src/cpu/io.o \ @@ -32,7 +35,6 @@ OBJS = \ src/sys/syscall.o \ src/sys/userspace_asm.o \ src/sys/userspace.o \ - src/ubsan/ubsan.o \ all: kernel.bin diff --git a/kernel/include/panic.h b/kernel/include/panic.h new file mode 100644 index 0000000..23b02f4 --- /dev/null +++ b/kernel/include/panic.h @@ -0,0 +1,6 @@ +#ifndef PANIC_H +#define PANIC_H + +__attribute__((noreturn)) void panic(void); + +#endif diff --git a/kernel/src/check/panic.c b/kernel/src/check/panic.c new file mode 100644 index 0000000..0480633 --- /dev/null +++ b/kernel/src/check/panic.c @@ -0,0 +1,12 @@ +#include +#include + +__attribute__((noreturn)) +void panic() +{ + printf("PANIC MODE ENETERED"); + __asm__ volatile ("cli;"); + for(;;) { + __asm__ volatile ("hlt;"); + } +} diff --git a/kernel/src/check/ssp.c b/kernel/src/check/ssp.c new file mode 100644 index 0000000..4b9c72a --- /dev/null +++ b/kernel/src/check/ssp.c @@ -0,0 +1,14 @@ +#include +#include +#include + +#define STACK_CHK_GUARD 0xdeadbeefcafebabe + +uintptr_t __stack_chk_guard = STACK_CHK_GUARD; + +__attribute__((noreturn)) +void __stack_chk_fail(void) +{ + printf("Stack smashing detected"); + panic(); +} diff --git a/kernel/src/check/ubsan.c b/kernel/src/check/ubsan.c new file mode 100644 index 0000000..8a5f998 --- /dev/null +++ b/kernel/src/check/ubsan.c @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2014, 2015 Jonas 'Sortie' Termansen. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ubsan/ubsan.c + * Undefined behavior sanitizer runtime support. + */ + +#include +#include +#include +#include +#include + +struct ubsan_source_location +{ + const char* filename; + uint32_t line; + uint32_t column; +}; + +struct ubsan_type_descriptor +{ + uint16_t type_kind; + uint16_t type_info; + char type_name[]; +}; + +typedef uintptr_t ubsan_value_handle_t; + +static const struct ubsan_source_location unknown_location = +{ + "", + 0, + 0, +}; + +__attribute__((noreturn)) +static void ubsan_abort(const struct ubsan_source_location* location, + const char* violation) +{ + if ( !location || !location->filename ) + location = &unknown_location; + + printf( + "filename = %s; line = %d; column = %d; violation = %s;\n", + location->filename, location->line, location->column, violation); + panic(); +} + +#define ABORT_VARIANT(name, params, call) \ +__attribute__((noreturn)) \ +void __ubsan_handle_##name##_abort params \ +{ \ + __ubsan_handle_##name call; \ + __builtin_unreachable(); \ +} + +#define ABORT_VARIANT_VP(name) \ +ABORT_VARIANT(name, (void* a), (a)) +#define ABORT_VARIANT_VP_VP(name) \ +ABORT_VARIANT(name, (void* a, void* b), (a, b)) +#define ABORT_VARIANT_VP_IP(name) \ +ABORT_VARIANT(name, (void* a, intptr_t b), (a, b)) +#define ABORT_VARIANT_VP_VP_VP(name) \ +ABORT_VARIANT(name, (void* a, void* b, void* c), (a, b, c)) + +struct ubsan_type_mismatch_v1_data +{ + struct ubsan_source_location location; + struct ubsan_type_descriptor* type; + uintptr_t alignment; + unsigned char type_check_kind; +}; + +void __ubsan_handle_type_mismatch_v1(void* data_raw, + void* pointer_raw) +{ + struct ubsan_type_mismatch_v1_data* data = + (struct ubsan_type_mismatch_v1_data*) data_raw; + ubsan_value_handle_t pointer = (ubsan_value_handle_t) pointer_raw; + const char* violation = "type mismatch"; + if ( !pointer ) + violation = "null pointer access"; + else if ( data->alignment && (pointer & (data->alignment - 1)) ) + violation = "unaligned access"; + ubsan_abort(&data->location, violation); +} + +ABORT_VARIANT_VP_VP(type_mismatch_v1); + +struct ubsan_overflow_data +{ + struct ubsan_source_location location; + struct ubsan_type_descriptor* type; +}; + +void __ubsan_handle_pointer_overflow(void* data_raw, + void* lhs_raw, + void* rhs_raw) +{ + struct ubsan_overflow_data* data = (struct ubsan_overflow_data*) data_raw; + ubsan_value_handle_t lhs = (ubsan_value_handle_t) lhs_raw; + ubsan_value_handle_t rhs = (ubsan_value_handle_t) rhs_raw; + (void) lhs; + (void) rhs; + ubsan_abort(&data->location, "pointer overflow"); +} + +ABORT_VARIANT_VP_VP_VP(pointer_overflow); + +void __ubsan_handle_add_overflow(void* data_raw, + void* lhs_raw, + void* rhs_raw) +{ + struct ubsan_overflow_data* data = (struct ubsan_overflow_data*) data_raw; + ubsan_value_handle_t lhs = (ubsan_value_handle_t) lhs_raw; + ubsan_value_handle_t rhs = (ubsan_value_handle_t) rhs_raw; + (void) lhs; + (void) rhs; + ubsan_abort(&data->location, "addition overflow"); +} + +ABORT_VARIANT_VP_VP_VP(add_overflow); + +void __ubsan_handle_sub_overflow(void* data_raw, + void* lhs_raw, + void* rhs_raw) +{ + struct ubsan_overflow_data* data = (struct ubsan_overflow_data*) data_raw; + ubsan_value_handle_t lhs = (ubsan_value_handle_t) lhs_raw; + ubsan_value_handle_t rhs = (ubsan_value_handle_t) rhs_raw; + (void) lhs; + (void) rhs; + ubsan_abort(&data->location, "subtraction overflow"); +} + +ABORT_VARIANT_VP_VP_VP(sub_overflow); + +void __ubsan_handle_mul_overflow(void* data_raw, + void* lhs_raw, + void* rhs_raw) +{ + struct ubsan_overflow_data* data = (struct ubsan_overflow_data*) data_raw; + ubsan_value_handle_t lhs = (ubsan_value_handle_t) lhs_raw; + ubsan_value_handle_t rhs = (ubsan_value_handle_t) rhs_raw; + (void) lhs; + (void) rhs; + ubsan_abort(&data->location, "multiplication overflow"); +} + +ABORT_VARIANT_VP_VP_VP(mul_overflow); + +void __ubsan_handle_negate_overflow(void* data_raw, + void* old_value_raw) +{ + struct ubsan_overflow_data* data = (struct ubsan_overflow_data*) data_raw; + ubsan_value_handle_t old_value = (ubsan_value_handle_t) old_value_raw; + (void) old_value; + ubsan_abort(&data->location, "negation overflow"); +} + +ABORT_VARIANT_VP_VP(negate_overflow); + +void __ubsan_handle_divrem_overflow(void* data_raw, + void* lhs_raw, + void* rhs_raw) +{ + struct ubsan_overflow_data* data = (struct ubsan_overflow_data*) data_raw; + ubsan_value_handle_t lhs = (ubsan_value_handle_t) lhs_raw; + ubsan_value_handle_t rhs = (ubsan_value_handle_t) rhs_raw; + (void) lhs; + (void) rhs; + ubsan_abort(&data->location, "division remainder overflow"); +} + +ABORT_VARIANT_VP_VP_VP(divrem_overflow); + +struct ubsan_shift_out_of_bounds_data +{ + struct ubsan_source_location location; + struct ubsan_type_descriptor* lhs_type; + struct ubsan_type_descriptor* rhs_type; +}; + +void __ubsan_handle_shift_out_of_bounds(void* data_raw, + void* lhs_raw, + void* rhs_raw) +{ + struct ubsan_shift_out_of_bounds_data* data = + (struct ubsan_shift_out_of_bounds_data*) data_raw; + ubsan_value_handle_t lhs = (ubsan_value_handle_t) lhs_raw; + ubsan_value_handle_t rhs = (ubsan_value_handle_t) rhs_raw; + (void) lhs; + (void) rhs; + ubsan_abort(&data->location, "shift out of bounds"); +} + +ABORT_VARIANT_VP_VP_VP(shift_out_of_bounds); + +struct ubsan_out_of_bounds_data +{ + struct ubsan_source_location location; + struct ubsan_type_descriptor* array_type; + struct ubsan_type_descriptor* index_type; +}; + +void __ubsan_handle_out_of_bounds(void* data_raw, + void* index_raw) +{ + struct ubsan_out_of_bounds_data* data = + (struct ubsan_out_of_bounds_data*) data_raw; + ubsan_value_handle_t index = (ubsan_value_handle_t) index_raw; + (void) index; + ubsan_abort(&data->location, "out of bounds"); +} + +ABORT_VARIANT_VP_VP(out_of_bounds); + +struct ubsan_unreachable_data +{ + struct ubsan_source_location location; +}; + +__attribute__((noreturn)) +void __ubsan_handle_builtin_unreachable(void* data_raw) +{ + struct ubsan_unreachable_data* data = + (struct ubsan_unreachable_data*) data_raw; + ubsan_abort(&data->location, "reached unreachable"); +} + +__attribute__((noreturn)) +void __ubsan_handle_missing_return(void* data_raw) +{ + struct ubsan_unreachable_data* data = + (struct ubsan_unreachable_data*) data_raw; + ubsan_abort(&data->location, "missing return"); +} + +struct ubsan_vla_bound_data +{ + struct ubsan_source_location location; + struct ubsan_type_descriptor* type; +}; + +void __ubsan_handle_vla_bound_not_positive(void* data_raw, + void* bound_raw) +{ + struct ubsan_vla_bound_data* data = (struct ubsan_vla_bound_data*) data_raw; + ubsan_value_handle_t bound = (ubsan_value_handle_t) bound_raw; + (void) bound; + ubsan_abort(&data->location, "negative variable array length"); +} + +ABORT_VARIANT_VP_VP(vla_bound_not_positive); + +struct ubsan_float_cast_overflow_data +{ + // TODO: Remove this GCC 5.x compatibility after switching to GCC 6.x. The + // GCC developers accidentally forgot the source location. Their + // libubsan probes to see if it looks like a path, but we don't need + // to maintain compatibility with multiple gcc releases. See below. +#if !(defined(__GNUC__) && __GNUC__< 6) + struct ubsan_source_location location; +#endif + struct ubsan_type_descriptor* from_type; + struct ubsan_type_descriptor* to_type; +}; + +void __ubsan_handle_float_cast_overflow(void* data_raw, + void* from_raw) +{ + struct ubsan_float_cast_overflow_data* data = + (struct ubsan_float_cast_overflow_data*) data_raw; + ubsan_value_handle_t from = (ubsan_value_handle_t) from_raw; + (void) from; +#if !(defined(__GNUC__) && __GNUC__< 6) + ubsan_abort(&data->location, "float cast overflow"); +#else + ubsan_abort(((void) data, &unknown_location), "float cast overflow"); +#endif +} + +ABORT_VARIANT_VP_VP(float_cast_overflow); + +struct ubsan_invalid_value_data +{ + struct ubsan_source_location location; + struct ubsan_type_descriptor* type; +}; + +void __ubsan_handle_load_invalid_value(void* data_raw, + void* value_raw) +{ + struct ubsan_invalid_value_data* data = + (struct ubsan_invalid_value_data*) data_raw; + ubsan_value_handle_t value = (ubsan_value_handle_t) value_raw; + (void) value; + ubsan_abort(&data->location, "invalid value load"); +} + +ABORT_VARIANT_VP_VP(load_invalid_value); + +struct ubsan_function_type_mismatch_v1_data +{ + struct ubsan_source_location location; + struct ubsan_type_descriptor* type; +}; + +void __ubsan_handle_function_type_mismatch_v1(void* data_raw, + void* value_raw) +{ + struct ubsan_function_type_mismatch_v1_data* data = + (struct ubsan_function_type_mismatch_v1_data*) data_raw; + ubsan_value_handle_t value = (ubsan_value_handle_t) value_raw; + (void) value; + ubsan_abort(&data->location, "function type mismatch"); +} + +ABORT_VARIANT_VP_VP(function_type_mismatch_v1); + +struct ubsan_nonnull_return_data +{ + struct ubsan_source_location location; + struct ubsan_source_location attr_location; +}; + +void __ubsan_handle_nonnull_return(void* data_raw) +{ + struct ubsan_nonnull_return_data* data = + (struct ubsan_nonnull_return_data*) data_raw; + ubsan_abort(&data->location, "null return"); +} + +ABORT_VARIANT_VP(nonnull_return); + +struct ubsan_nonnull_arg_data +{ + struct ubsan_source_location location; + struct ubsan_source_location attr_location; +}; + +// TODO: GCC's libubsan does not have the second parameter, but its builtin +// somehow has it and conflict if we don't match it. +void __ubsan_handle_nonnull_arg(void* data_raw, + intptr_t index_raw) +{ + struct ubsan_nonnull_arg_data* data = + (struct ubsan_nonnull_arg_data*) data_raw; + ubsan_value_handle_t index = (ubsan_value_handle_t) index_raw; + (void) index; + ubsan_abort(&data->location, "null argument"); +} + +ABORT_VARIANT_VP_IP(nonnull_arg); + +struct ubsan_cfi_bad_icall_data +{ + struct ubsan_source_location location; + struct ubsan_type_descriptor* type; +}; + +void __ubsan_handle_cfi_bad_icall(void* data_raw, + void* value_raw) +{ + struct ubsan_cfi_bad_icall_data* data = + (struct ubsan_cfi_bad_icall_data*) data_raw; + ubsan_value_handle_t value = (ubsan_value_handle_t) value_raw; + (void) value; + ubsan_abort(&data->location, + "control flow integrity check failure during indirect call"); +} + +ABORT_VARIANT_VP_VP(cfi_bad_icall); diff --git a/kernel/src/cpu/irq.c b/kernel/src/cpu/irq.c index 2695d4d..a345251 100644 --- a/kernel/src/cpu/irq.c +++ b/kernel/src/cpu/irq.c @@ -8,6 +8,7 @@ #include #include #include +#include const char* const exception_name[] = { "Divide-by-zero Error", @@ -47,41 +48,49 @@ const char* const exception_name[] = { void isr0_handler(void) { printf("%s\n", exception_name[0]); + panic(); } void isr1_handler(void) { printf("%s\n", exception_name[1]); + panic(); } void isr2_handler(void) { printf("%s\n", exception_name[2]); + panic(); } void isr3_handler(void) { printf("%s\n", exception_name[3]); + panic(); } void isr4_handler(void) { printf("%s\n", exception_name[4]); + panic(); } void isr5_handler(void) { printf("%s\n", exception_name[5]); + panic(); } void isr6_handler(void) { printf("%s\n", exception_name[6]); + panic(); } void isr7_handler(void) { printf("%s\n", exception_name[7]); + panic(); } void isr8_handler(uint64_t error) @@ -93,30 +102,35 @@ void isr8_handler(uint64_t error) void isr9_handler(void) { printf("%s\n", exception_name[9]); + panic(); } void isr10_handler(uint64_t error) { printf("%s\n", exception_name[10]); printf("error: %d\n", error); + panic(); } void isr11_handler(uint64_t error) { printf("%s\n", exception_name[11]); printf("error: %d\n", error); + panic(); } void isr12_handler(uint64_t error) { printf("%s\n", exception_name[12]); printf("error: %d\n", error); + panic(); } void isr13_handler(uint64_t error) { printf("%s\n", exception_name[13]); printf("error: %d\n", error); + panic(); } void isr14_handler(uint64_t error) @@ -129,90 +143,107 @@ void isr14_handler(uint64_t error) void isr15_handler(void) { printf("%s\n", exception_name[15]); + panic(); } void isr16_handler(void) { printf("%s\n", exception_name[16]); + panic(); } void isr17_handler(uint64_t error) { printf("%s\n", exception_name[17]); printf("error: %d\n", error); + panic(); } void isr18_handler(void) { printf("%s\n", exception_name[18]); + panic(); } void isr19_handler(void) { printf("%s\n", exception_name[19]); + panic(); } void isr20_handler(void) { printf("%s\n", exception_name[20]); + panic(); } void isr21_handler(uint64_t error) { printf("%s\n", exception_name[21]); printf("error: %d\n", error); + panic(); } void isr22_handler(void) { printf("%s\n", exception_name[22]); + panic(); } void isr23_handler(void) { printf("%s\n", exception_name[23]); + panic(); } void isr24_handler(void) { printf("%s\n", exception_name[24]); + panic(); } void isr25_handler(void) { printf("%s\n", exception_name[25]); + panic(); } void isr26_handler(void) { printf("%s\n", exception_name[26]); + panic(); } void isr27_handler(void) { printf("%s\n", exception_name[27]); + panic(); } void isr28_handler(void) { printf("%s\n", exception_name[28]); + panic(); } void isr29_handler(uint64_t error) { printf("%s\n", exception_name[29]); printf("error: %d\n", error); + panic(); } void isr30_handler(uint64_t error) { printf("%s\n", exception_name[30]); printf("error: %d\n", error); + panic(); } void isr31_handler(void) { printf("%s\n", exception_name[31]); + panic(); } void irq0_handler(void) diff --git a/kernel/src/ubsan/ubsan.c b/kernel/src/ubsan/ubsan.c deleted file mode 100644 index 9cd744d..0000000 --- a/kernel/src/ubsan/ubsan.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (c) 2014, 2015 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * ubsan/ubsan.c - * Undefined behavior sanitizer runtime support. - */ - -#include -#include -#include -#include - -struct ubsan_source_location -{ - const char* filename; - uint32_t line; - uint32_t column; -}; - -struct ubsan_type_descriptor -{ - uint16_t type_kind; - uint16_t type_info; - char type_name[]; -}; - -typedef uintptr_t ubsan_value_handle_t; - -static const struct ubsan_source_location unknown_location = -{ - "", - 0, - 0, -}; - -__attribute__((noreturn)) -static void ubsan_abort(const struct ubsan_source_location* location, - const char* violation) -{ - if ( !location || !location->filename ) - location = &unknown_location; - - printf( - "filename = %s; line = %d; column = %d; violation = %s;\n", - location->filename, location->line, location->column, violation); - - for(;;) { - __asm__ volatile ("hlt;"); - } -} - -#define ABORT_VARIANT(name, params, call) \ -__attribute__((noreturn)) \ -void __ubsan_handle_##name##_abort params \ -{ \ - __ubsan_handle_##name call; \ - __builtin_unreachable(); \ -} - -#define ABORT_VARIANT_VP(name) \ -ABORT_VARIANT(name, (void* a), (a)) -#define ABORT_VARIANT_VP_VP(name) \ -ABORT_VARIANT(name, (void* a, void* b), (a, b)) -#define ABORT_VARIANT_VP_IP(name) \ -ABORT_VARIANT(name, (void* a, intptr_t b), (a, b)) -#define ABORT_VARIANT_VP_VP_VP(name) \ -ABORT_VARIANT(name, (void* a, void* b, void* c), (a, b, c)) - -struct ubsan_type_mismatch_v1_data -{ - struct ubsan_source_location location; - struct ubsan_type_descriptor* type; - uintptr_t alignment; - unsigned char type_check_kind; -}; - -void __ubsan_handle_type_mismatch_v1(void* data_raw, - void* pointer_raw) -{ - struct ubsan_type_mismatch_v1_data* data = - (struct ubsan_type_mismatch_v1_data*) data_raw; - ubsan_value_handle_t pointer = (ubsan_value_handle_t) pointer_raw; - const char* violation = "type mismatch"; - if ( !pointer ) - violation = "null pointer access"; - else if ( data->alignment && (pointer & (data->alignment - 1)) ) - violation = "unaligned access"; - ubsan_abort(&data->location, violation); -} - -ABORT_VARIANT_VP_VP(type_mismatch_v1); - -struct ubsan_overflow_data -{ - struct ubsan_source_location location; - struct ubsan_type_descriptor* type; -}; - -void __ubsan_handle_pointer_overflow(void* data_raw, - void* lhs_raw, - void* rhs_raw) -{ - struct ubsan_overflow_data* data = (struct ubsan_overflow_data*) data_raw; - ubsan_value_handle_t lhs = (ubsan_value_handle_t) lhs_raw; - ubsan_value_handle_t rhs = (ubsan_value_handle_t) rhs_raw; - (void) lhs; - (void) rhs; - ubsan_abort(&data->location, "pointer overflow"); -} - -ABORT_VARIANT_VP_VP_VP(pointer_overflow); - -void __ubsan_handle_add_overflow(void* data_raw, - void* lhs_raw, - void* rhs_raw) -{ - struct ubsan_overflow_data* data = (struct ubsan_overflow_data*) data_raw; - ubsan_value_handle_t lhs = (ubsan_value_handle_t) lhs_raw; - ubsan_value_handle_t rhs = (ubsan_value_handle_t) rhs_raw; - (void) lhs; - (void) rhs; - ubsan_abort(&data->location, "addition overflow"); -} - -ABORT_VARIANT_VP_VP_VP(add_overflow); - -void __ubsan_handle_sub_overflow(void* data_raw, - void* lhs_raw, - void* rhs_raw) -{ - struct ubsan_overflow_data* data = (struct ubsan_overflow_data*) data_raw; - ubsan_value_handle_t lhs = (ubsan_value_handle_t) lhs_raw; - ubsan_value_handle_t rhs = (ubsan_value_handle_t) rhs_raw; - (void) lhs; - (void) rhs; - ubsan_abort(&data->location, "subtraction overflow"); -} - -ABORT_VARIANT_VP_VP_VP(sub_overflow); - -void __ubsan_handle_mul_overflow(void* data_raw, - void* lhs_raw, - void* rhs_raw) -{ - struct ubsan_overflow_data* data = (struct ubsan_overflow_data*) data_raw; - ubsan_value_handle_t lhs = (ubsan_value_handle_t) lhs_raw; - ubsan_value_handle_t rhs = (ubsan_value_handle_t) rhs_raw; - (void) lhs; - (void) rhs; - ubsan_abort(&data->location, "multiplication overflow"); -} - -ABORT_VARIANT_VP_VP_VP(mul_overflow); - -void __ubsan_handle_negate_overflow(void* data_raw, - void* old_value_raw) -{ - struct ubsan_overflow_data* data = (struct ubsan_overflow_data*) data_raw; - ubsan_value_handle_t old_value = (ubsan_value_handle_t) old_value_raw; - (void) old_value; - ubsan_abort(&data->location, "negation overflow"); -} - -ABORT_VARIANT_VP_VP(negate_overflow); - -void __ubsan_handle_divrem_overflow(void* data_raw, - void* lhs_raw, - void* rhs_raw) -{ - struct ubsan_overflow_data* data = (struct ubsan_overflow_data*) data_raw; - ubsan_value_handle_t lhs = (ubsan_value_handle_t) lhs_raw; - ubsan_value_handle_t rhs = (ubsan_value_handle_t) rhs_raw; - (void) lhs; - (void) rhs; - ubsan_abort(&data->location, "division remainder overflow"); -} - -ABORT_VARIANT_VP_VP_VP(divrem_overflow); - -struct ubsan_shift_out_of_bounds_data -{ - struct ubsan_source_location location; - struct ubsan_type_descriptor* lhs_type; - struct ubsan_type_descriptor* rhs_type; -}; - -void __ubsan_handle_shift_out_of_bounds(void* data_raw, - void* lhs_raw, - void* rhs_raw) -{ - struct ubsan_shift_out_of_bounds_data* data = - (struct ubsan_shift_out_of_bounds_data*) data_raw; - ubsan_value_handle_t lhs = (ubsan_value_handle_t) lhs_raw; - ubsan_value_handle_t rhs = (ubsan_value_handle_t) rhs_raw; - (void) lhs; - (void) rhs; - ubsan_abort(&data->location, "shift out of bounds"); -} - -ABORT_VARIANT_VP_VP_VP(shift_out_of_bounds); - -struct ubsan_out_of_bounds_data -{ - struct ubsan_source_location location; - struct ubsan_type_descriptor* array_type; - struct ubsan_type_descriptor* index_type; -}; - -void __ubsan_handle_out_of_bounds(void* data_raw, - void* index_raw) -{ - struct ubsan_out_of_bounds_data* data = - (struct ubsan_out_of_bounds_data*) data_raw; - ubsan_value_handle_t index = (ubsan_value_handle_t) index_raw; - (void) index; - ubsan_abort(&data->location, "out of bounds"); -} - -ABORT_VARIANT_VP_VP(out_of_bounds); - -struct ubsan_unreachable_data -{ - struct ubsan_source_location location; -}; - -__attribute__((noreturn)) -void __ubsan_handle_builtin_unreachable(void* data_raw) -{ - struct ubsan_unreachable_data* data = - (struct ubsan_unreachable_data*) data_raw; - ubsan_abort(&data->location, "reached unreachable"); -} - -__attribute__((noreturn)) -void __ubsan_handle_missing_return(void* data_raw) -{ - struct ubsan_unreachable_data* data = - (struct ubsan_unreachable_data*) data_raw; - ubsan_abort(&data->location, "missing return"); -} - -struct ubsan_vla_bound_data -{ - struct ubsan_source_location location; - struct ubsan_type_descriptor* type; -}; - -void __ubsan_handle_vla_bound_not_positive(void* data_raw, - void* bound_raw) -{ - struct ubsan_vla_bound_data* data = (struct ubsan_vla_bound_data*) data_raw; - ubsan_value_handle_t bound = (ubsan_value_handle_t) bound_raw; - (void) bound; - ubsan_abort(&data->location, "negative variable array length"); -} - -ABORT_VARIANT_VP_VP(vla_bound_not_positive); - -struct ubsan_float_cast_overflow_data -{ - // TODO: Remove this GCC 5.x compatibility after switching to GCC 6.x. The - // GCC developers accidentally forgot the source location. Their - // libubsan probes to see if it looks like a path, but we don't need - // to maintain compatibility with multiple gcc releases. See below. -#if !(defined(__GNUC__) && __GNUC__< 6) - struct ubsan_source_location location; -#endif - struct ubsan_type_descriptor* from_type; - struct ubsan_type_descriptor* to_type; -}; - -void __ubsan_handle_float_cast_overflow(void* data_raw, - void* from_raw) -{ - struct ubsan_float_cast_overflow_data* data = - (struct ubsan_float_cast_overflow_data*) data_raw; - ubsan_value_handle_t from = (ubsan_value_handle_t) from_raw; - (void) from; -#if !(defined(__GNUC__) && __GNUC__< 6) - ubsan_abort(&data->location, "float cast overflow"); -#else - ubsan_abort(((void) data, &unknown_location), "float cast overflow"); -#endif -} - -ABORT_VARIANT_VP_VP(float_cast_overflow); - -struct ubsan_invalid_value_data -{ - struct ubsan_source_location location; - struct ubsan_type_descriptor* type; -}; - -void __ubsan_handle_load_invalid_value(void* data_raw, - void* value_raw) -{ - struct ubsan_invalid_value_data* data = - (struct ubsan_invalid_value_data*) data_raw; - ubsan_value_handle_t value = (ubsan_value_handle_t) value_raw; - (void) value; - ubsan_abort(&data->location, "invalid value load"); -} - -ABORT_VARIANT_VP_VP(load_invalid_value); - -struct ubsan_function_type_mismatch_v1_data -{ - struct ubsan_source_location location; - struct ubsan_type_descriptor* type; -}; - -void __ubsan_handle_function_type_mismatch_v1(void* data_raw, - void* value_raw) -{ - struct ubsan_function_type_mismatch_v1_data* data = - (struct ubsan_function_type_mismatch_v1_data*) data_raw; - ubsan_value_handle_t value = (ubsan_value_handle_t) value_raw; - (void) value; - ubsan_abort(&data->location, "function type mismatch"); -} - -ABORT_VARIANT_VP_VP(function_type_mismatch_v1); - -struct ubsan_nonnull_return_data -{ - struct ubsan_source_location location; - struct ubsan_source_location attr_location; -}; - -void __ubsan_handle_nonnull_return(void* data_raw) -{ - struct ubsan_nonnull_return_data* data = - (struct ubsan_nonnull_return_data*) data_raw; - ubsan_abort(&data->location, "null return"); -} - -ABORT_VARIANT_VP(nonnull_return); - -struct ubsan_nonnull_arg_data -{ - struct ubsan_source_location location; - struct ubsan_source_location attr_location; -}; - -// TODO: GCC's libubsan does not have the second parameter, but its builtin -// somehow has it and conflict if we don't match it. -void __ubsan_handle_nonnull_arg(void* data_raw, - intptr_t index_raw) -{ - struct ubsan_nonnull_arg_data* data = - (struct ubsan_nonnull_arg_data*) data_raw; - ubsan_value_handle_t index = (ubsan_value_handle_t) index_raw; - (void) index; - ubsan_abort(&data->location, "null argument"); -} - -ABORT_VARIANT_VP_IP(nonnull_arg); - -struct ubsan_cfi_bad_icall_data -{ - struct ubsan_source_location location; - struct ubsan_type_descriptor* type; -}; - -void __ubsan_handle_cfi_bad_icall(void* data_raw, - void* value_raw) -{ - struct ubsan_cfi_bad_icall_data* data = - (struct ubsan_cfi_bad_icall_data*) data_raw; - ubsan_value_handle_t value = (ubsan_value_handle_t) value_raw; - (void) value; - ubsan_abort(&data->location, - "control flow integrity check failure during indirect call"); -} - -ABORT_VARIANT_VP_VP(cfi_bad_icall); -- cgit v1.2.3