From dbf485d61cd40fa20f025ecb6012b114463618ea Mon Sep 17 00:00:00 2001 From: Eric Chan Date: Wed, 10 Jul 2024 17:58:37 +0000 Subject: [PATCH] [ubsan] Add some handlers that do not yet exist and fix some format errors Add handlers as below: 1. __ubsan_handle_function_type_mismatch 2. __ubsan_handle_alignment_assumption 3. __ubsan_handle_float_cast_overflow Also fix the format errors for compiling and printing. Test log is as below: start test_ubsan_function_type_mismatch ... ===================================UBSAN error=================================== ubsan: function type mismatch in lk/lib/test_ubsan/test_ubsan.c:191:5 Call function(0x12e8d) through pointer with incompatible type 'void (*)(void)' ================================================================================= start test_ubsan_alignment_assumption ... alignment assumption ===================================UBSAN error=================================== ubsan: Alignment Error in lk/lib/test_ubsan/test_ubsan.c:217:11 assumption of 32 byte alignment for pointer of type 'void *' failed address is 2 aligned, misalignment offset is 3 bytes ================================================================================= alignment assumption offset ===================================UBSAN error=================================== ubsan: Alignment Error in lk/lib/test_ubsan/test_ubsan.c:218:11 assumption of 32 byte alignment (with offset of 4 byte) for pointer of type 'void *' failed offset address is 2 aligned, misalignment offset is 31 bytes ================================================================================= start test_ubsan_float_cast_overflow ... ===================================UBSAN error=================================== ubsan: Float Cast Overflow in lk/lib/test_ubsan/test_ubsan.c:82:12 value 'double' is outside of the range of representable value of type 'unsigned int' at 0x2001d3e8 ================================================================================= --- lib/ubsan/ubsan.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/lib/ubsan/ubsan.cpp b/lib/ubsan/ubsan.cpp index 1f09f43f8..cab3b831c 100644 --- a/lib/ubsan/ubsan.cpp +++ b/lib/ubsan/ubsan.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -172,7 +173,7 @@ static void ubsan_report_end() static void do_ubsan_type_mismatch_nullptr(const ubsan_type_mismatch_data *data, size_t ptr) { ubsan_report_start(&data->location, "Null pointer dereference"); - printf("%s null pointer of type %sn", type_check_kinds[data->type_check_kind], + printf("%s null pointer of type %s\n", type_check_kinds[data->type_check_kind], data->type->typename_); ubsan_report_end(); } @@ -189,7 +190,7 @@ static void do_ubsan_type_mismatch_unaligned(const ubsan_type_mismatch_data *dat static void do_ubsan_type_mismatch_objsize(const ubsan_type_mismatch_data *data, size_t ptr) { ubsan_report_start(&data->location, "Insufficient object size"); - printf("%s address %p with insuficient space for type %s\n", + printf("%s address %p with insufficient space for type %s\n", type_check_kinds[data->type_check_kind], (void *) ptr, data->type->typename_); ubsan_report_end(); } @@ -314,7 +315,7 @@ static void ubsan_handle_integer_overflow(const ubsan_overflow_data *data, size_ ubsan_report_start(&data->location, "Integer overflow"); - printf("%s integer overflow: %s %s %s can't be represented in type %s", + printf("%s integer overflow: %s %s %s can't be represented in type %s\n", signed_ ? "signed" : "unsigned", lhs_v.to_string().c_str(), op, rhs_v.to_string().c_str(), data->type->typename_); ubsan_report_end(); @@ -557,6 +558,79 @@ __USED void __ubsan_handle_vla_bound_not_positive_abort(ubsan_vla_bound_data *da ubsan_abort(); } +struct ubsan_function_type_mismatch_data { + ubsan_source_location location; + ubsan_type_descriptor *type; + val function_ptr; +}; + +__USED void __ubsan_handle_function_type_mismatch(ubsan_function_type_mismatch_data *data, size_t ptr) +{ + ubsan_report_start(&data->location, "function type mismatch"); + printf("Call function(%p) through pointer with incompatible type %s\n", + (void *) ptr, data->type->typename_); + ubsan_report_end(); +} + +__USED void __ubsan_handle_function_type_mismatch_abort(ubsan_function_type_mismatch_data *data, size_t ptr) +{ + __ubsan_handle_function_type_mismatch(data, ptr); + ubsan_abort(); +} + +struct ubsan_alignment_assumption_data { + struct ubsan_source_location location; + struct ubsan_source_location assumption_location; + struct ubsan_type_descriptor *type; +}; + +__USED void __ubsan_handle_alignment_assumption(ubsan_alignment_assumption_data *data, ssize_t ptr, + ssize_t align, ssize_t offset) +{ + ssize_t real_ptr; + ubsan_report_start(&data->location, "Alignment Error"); + if (offset) + printf("assumption of %zd byte alignment (with offset of %zd byte) for pointer of type %s failed", + align, offset, data->type->typename_); + else + printf("assumption of %zd byte alignment for pointer of type %s failed", + align, data->type->typename_); + + real_ptr = ptr - offset; + printf(" %saddress is %lu aligned, misalignment offset is %zd bytes\n", + offset ? "offset " : "", real_ptr ? (1 << ffs(real_ptr)) : 1, + real_ptr & (align - 1)); + + ubsan_report_end(); +} + +__USED void __ubsan_handle_alignment_assumption_abort(ubsan_alignment_assumption_data *data, + ssize_t ptr, ssize_t align, ssize_t offset) +{ + __ubsan_handle_alignment_assumption(data, ptr, align, offset); + ubsan_abort(); +} + +struct ubsan_float_cast_data { + struct ubsan_source_location location; + struct ubsan_type_descriptor *from_type; + struct ubsan_type_descriptor *to_type; +}; + +__USED void __ubsan_handle_float_cast_overflow(ubsan_float_cast_data *data, size_t ptr) +{ + ubsan_report_start(&data->location, "Float Cast Overflow"); + printf("value %s is outside of the range of representable value of type %s at %p\n", + data->from_type->typename_, data->to_type->typename_, (void *) ptr); + ubsan_report_end(); +} + +__USED void __ubsan_handle_float_cast_overflow_abort(ubsan_float_cast_data *data, size_t ptr) +{ + __ubsan_handle_float_cast_overflow(data, ptr); + ubsan_abort(); +} + // Note: we used to have __ubsan_handle_function_type_mismatch but it seems to have been dropped // from both GCC and clang