summaryrefslogtreecommitdiff
path: root/kernel/src/ubsan/ubsan.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/src/ubsan/ubsan.c')
-rw-r--r--kernel/src/ubsan/ubsan.c388
1 files changed, 0 insertions, 388 deletions
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 <stdint.h>
-#include <libk/stdio.h>
-#include <libk/serial_stdio.h>
-#include <ubsan.h>
-
-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 =
-{
- "<unknown file>",
- 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);