diff --git a/AK/UBSanitizer.h b/AK/UBSanitizer.h index 326972e0e0c..23157ab5b16 100644 --- a/AK/UBSanitizer.h +++ b/AK/UBSanitizer.h @@ -148,6 +148,11 @@ struct PointerOverflowData { SourceLocation location; }; +struct FunctionTypeMismatchData { + SourceLocation location; + TypeDescriptor const& type; +}; + struct FloatCastOverflowData { SourceLocation location; TypeDescriptor const& from_type; diff --git a/Kernel/Prekernel/UBSanitizer.cpp b/Kernel/Prekernel/UBSanitizer.cpp index 0da019c3d54..9f73d4fde32 100644 --- a/Kernel/Prekernel/UBSanitizer.cpp +++ b/Kernel/Prekernel/UBSanitizer.cpp @@ -141,4 +141,10 @@ void __ubsan_handle_pointer_overflow(PointerOverflowData const& data, ValueHandl { print_location(data.location); } + +void __ubsan_handle_function_type_mismatch(FunctionTypeMismatchData const&, ValueHandle) __attribute__((used)); +void __ubsan_handle_function_type_mismatch(FunctionTypeMismatchData const& data, ValueHandle) +{ + print_location(data.location); +} } diff --git a/Kernel/Security/UBSanitizer.cpp b/Kernel/Security/UBSanitizer.cpp index 5d714bcaea0..7e92fd9595c 100644 --- a/Kernel/Security/UBSanitizer.cpp +++ b/Kernel/Security/UBSanitizer.cpp @@ -208,4 +208,11 @@ void __ubsan_handle_pointer_overflow(PointerOverflowData const& data, ValueHandl critical_dmesgln("KUBSAN: addition of unsigned offset to {:p} overflowed to {:p}", base, result); print_location(data.location); } + +void __ubsan_handle_function_type_mismatch(FunctionTypeMismatchData const&) __attribute__((used)); +void __ubsan_handle_function_type_mismatch(FunctionTypeMismatchData const& data) +{ + critical_dmesgln("KUBSAN: call to function through pointer to incorrect function type {}", data.type.name()); + print_location(data.location); +} } diff --git a/Userland/Libraries/LibSanitizer/UBSanitizer.cpp b/Userland/Libraries/LibSanitizer/UBSanitizer.cpp index d4caf0a88a8..46b36819d77 100644 --- a/Userland/Libraries/LibSanitizer/UBSanitizer.cpp +++ b/Userland/Libraries/LibSanitizer/UBSanitizer.cpp @@ -482,4 +482,23 @@ static void handle_float_cast_overflow(FloatCastOverflowData& data, ValueHandle) handle_float_cast_overflow(data, value); ABORT_ALWAYS(); } + +static void handle_function_type_mismatch(FunctionTypeMismatchData& data, ValueHandle) +{ + auto location = data.location.permanently_clear(); + if (!location.needs_logging()) + return; + WARNLN_AND_DBGLN("UBSAN: call to function through pointer to incorrect function type {}", data.type.name()); + print_location(location); +} +[[gnu::used]] void __ubsan_handle_function_type_mismatch(FunctionTypeMismatchData& data, ValueHandle value) +{ + handle_function_type_mismatch(data, value); + ABORT_IF_DEADLY(); +} +[[gnu::used, noreturn]] void __ubsan_handle_function_type_mismatch_abort(FunctionTypeMismatchData& data, ValueHandle value) +{ + handle_function_type_mismatch(data, value); + ABORT_ALWAYS(); +} } // extern "C"