2021-02-05 21:44:26 +03:00
/*
* Copyright ( c ) 2021 , Andreas Kling < kling @ serenityos . org >
*
2021-04-22 11:24:48 +03:00
* SPDX - License - Identifier : BSD - 2 - Clause
2021-02-05 21:44:26 +03:00
*/
# include <AK/Format.h>
2021-05-24 04:33:40 +03:00
# include <AK/UBSanitizer.h>
2021-10-14 02:07:37 +03:00
# include <Kernel/Arch/Processor.h>
2021-02-05 21:44:26 +03:00
# include <Kernel/KSyms.h>
using namespace Kernel ;
2021-05-24 04:33:40 +03:00
using namespace AK : : UBSanitizer ;
2021-02-05 21:44:26 +03:00
2022-02-03 18:09:40 +03:00
Atomic < bool > AK : : UBSanitizer : : g_ubsan_is_deadly { true } ;
2021-03-05 00:07:23 +03:00
2021-02-05 21:44:26 +03:00
extern " C " {
2022-04-01 20:58:27 +03:00
static void print_location ( SourceLocation const & location )
2021-02-05 21:44:26 +03:00
{
2021-12-19 20:39:29 +03:00
if ( ! location . filename ( ) )
critical_dmesgln ( " KUBSAN: in unknown file " ) ;
else
critical_dmesgln ( " KUBSAN: at {}, line {}, column: {} " , location . filename ( ) , location . line ( ) , location . column ( ) ) ;
2021-12-29 18:40:33 +03:00
dump_backtrace ( g_ubsan_is_deadly ? PrintToScreen : : Yes : PrintToScreen : : No ) ;
2021-05-15 08:51:09 +03:00
if ( g_ubsan_is_deadly ) {
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " UB is configured to be deadly, halting the system. " ) ;
2021-05-15 08:51:09 +03:00
Processor : : halt ( ) ;
}
2021-02-05 21:44:26 +03:00
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_load_invalid_value ( InvalidValueData const & , ValueHandle ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_load_invalid_value ( InvalidValueData const & data , ValueHandle )
2021-02-05 21:44:26 +03:00
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: load-invalid-value: {} ({}-bit) " , data . type . name ( ) , data . type . bit_width ( ) ) ;
2021-02-05 21:44:26 +03:00
print_location ( data . location ) ;
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_nonnull_arg ( NonnullArgData const & ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_nonnull_arg ( NonnullArgData const & data )
2021-02-05 21:44:26 +03:00
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: null pointer passed as argument {}, which is declared to never be null " , data . argument_index ) ;
2021-02-05 21:44:26 +03:00
print_location ( data . location ) ;
2021-02-05 22:03:07 +03:00
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_nullability_arg ( NonnullArgData const & ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_nullability_arg ( NonnullArgData const & data )
2021-02-11 22:58:01 +03:00
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: null pointer passed as argument {}, which is declared to never be null " , data . argument_index ) ;
2021-02-11 22:58:01 +03:00
print_location ( data . location ) ;
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_nonnull_return_v1 ( NonnullReturnData const & , SourceLocation const & ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_nonnull_return_v1 ( NonnullReturnData const & , SourceLocation const & location )
2021-02-07 10:24:49 +03:00
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: null pointer return from function declared to never return null " ) ;
2021-02-07 10:24:49 +03:00
print_location ( location ) ;
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_nullability_return_v1 ( NonnullReturnData const & data , SourceLocation const & location ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_nullability_return_v1 ( NonnullReturnData const & , SourceLocation const & location )
2021-02-11 22:58:01 +03:00
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: null pointer return from function declared to never return null " ) ;
2021-02-11 22:58:01 +03:00
print_location ( location ) ;
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_vla_bound_not_positive ( VLABoundData const & , ValueHandle ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_vla_bound_not_positive ( VLABoundData const & data , ValueHandle )
2021-02-05 22:03:07 +03:00
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: VLA bound not positive {} ({}-bit) " , data . type . name ( ) , data . type . bit_width ( ) ) ;
2021-02-05 22:03:07 +03:00
print_location ( data . location ) ;
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_add_overflow ( OverflowData const & , ValueHandle lhs , ValueHandle rhs ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_add_overflow ( OverflowData const & data , ValueHandle , ValueHandle )
2021-02-05 22:03:07 +03:00
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: addition overflow, {} ({}-bit) " , data . type . name ( ) , data . type . bit_width ( ) ) ;
2021-02-11 22:58:01 +03:00
2021-02-05 22:03:07 +03:00
print_location ( data . location ) ;
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_sub_overflow ( OverflowData const & , ValueHandle lhs , ValueHandle rhs ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_sub_overflow ( OverflowData const & data , ValueHandle , ValueHandle )
2021-02-05 22:03:07 +03:00
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: subtraction overflow, {} ({}-bit) " , data . type . name ( ) , data . type . bit_width ( ) ) ;
2021-02-11 22:58:01 +03:00
2021-02-05 22:03:07 +03:00
print_location ( data . location ) ;
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_negate_overflow ( OverflowData const & , ValueHandle ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_negate_overflow ( OverflowData const & data , ValueHandle )
2021-02-05 22:03:07 +03:00
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: negation overflow, {} ({}-bit) " , data . type . name ( ) , data . type . bit_width ( ) ) ;
2021-02-11 22:58:01 +03:00
2021-02-05 22:03:07 +03:00
print_location ( data . location ) ;
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_mul_overflow ( OverflowData const & , ValueHandle lhs , ValueHandle rhs ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_mul_overflow ( OverflowData const & data , ValueHandle , ValueHandle )
2021-02-05 22:03:07 +03:00
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: multiplication overflow, {} ({}-bit) " , data . type . name ( ) , data . type . bit_width ( ) ) ;
2021-02-05 22:03:07 +03:00
print_location ( data . location ) ;
2021-02-05 21:44:26 +03:00
}
2021-02-06 18:08:30 +03:00
2022-04-01 20:58:27 +03:00
void __ubsan_handle_shift_out_of_bounds ( ShiftOutOfBoundsData const & , ValueHandle lhs , ValueHandle rhs ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_shift_out_of_bounds ( ShiftOutOfBoundsData const & data , ValueHandle , ValueHandle )
2021-02-06 18:08:30 +03:00
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: shift out of bounds, {} ({}-bit) shifted by {} ({}-bit) " , data . lhs_type . name ( ) , data . lhs_type . bit_width ( ) , data . rhs_type . name ( ) , data . rhs_type . bit_width ( ) ) ;
2021-02-06 18:08:30 +03:00
print_location ( data . location ) ;
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_divrem_overflow ( OverflowData const & , ValueHandle lhs , ValueHandle rhs ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_divrem_overflow ( OverflowData const & data , ValueHandle , ValueHandle )
2021-02-06 18:08:30 +03:00
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: divrem overflow, {} ({}-bit) " , data . type . name ( ) , data . type . bit_width ( ) ) ;
2021-02-06 18:08:30 +03:00
print_location ( data . location ) ;
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_out_of_bounds ( OutOfBoundsData const & , ValueHandle ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_out_of_bounds ( OutOfBoundsData const & data , ValueHandle )
2021-02-06 18:08:30 +03:00
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: out of bounds access into array of {} ({}-bit), index type {} ({}-bit) " , data . array_type . name ( ) , data . array_type . bit_width ( ) , data . index_type . name ( ) , data . index_type . bit_width ( ) ) ;
2021-02-06 18:08:30 +03:00
print_location ( data . location ) ;
}
2021-02-06 19:34:44 +03:00
2022-04-01 20:58:27 +03:00
void __ubsan_handle_type_mismatch_v1 ( TypeMismatchData const & , ValueHandle ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_type_mismatch_v1 ( TypeMismatchData const & data , ValueHandle ptr )
2021-02-24 16:27:06 +03:00
{
2021-05-19 17:35:09 +03:00
constexpr StringView kinds [ ] = {
2022-07-11 20:32:29 +03:00
" load of " sv ,
" store to " sv ,
" reference binding to " sv ,
" member access within " sv ,
" member call on " sv ,
" constructor call on " sv ,
" downcast of " sv ,
" downcast of " sv ,
" upcast of " sv ,
" cast to virtual base of " sv ,
" _Nonnull binding to " sv ,
" dynamic operation on " sv
2021-02-24 16:27:06 +03:00
} ;
FlatPtr alignment = ( FlatPtr ) 1 < < data . log_alignment ;
2021-05-19 17:35:09 +03:00
auto kind = kinds [ data . type_check_kind ] ;
2021-02-24 16:27:06 +03:00
2021-12-19 20:39:29 +03:00
if ( ! ptr )
critical_dmesgln ( " KUBSAN: {} null pointer of type {} " , kind , data . type . name ( ) ) ;
else if ( ( FlatPtr ) ptr & ( alignment - 1 ) )
critical_dmesgln ( " KUBSAN: {} misaligned address {:p} of type {} " , kind , ptr , data . type . name ( ) ) ;
else
critical_dmesgln ( " KUBSAN: {} address {:p} with insufficient space for type {} " , kind , ptr , data . type . name ( ) ) ;
2021-02-24 16:27:06 +03:00
2021-02-06 19:34:44 +03:00
print_location ( data . location ) ;
}
2021-02-11 22:58:01 +03:00
2022-04-01 20:58:27 +03:00
void __ubsan_handle_alignment_assumption ( AlignmentAssumptionData const & , ValueHandle , ValueHandle , ValueHandle ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_alignment_assumption ( AlignmentAssumptionData const & data , ValueHandle pointer , ValueHandle alignment , ValueHandle offset )
2021-02-11 22:58:01 +03:00
{
2021-12-19 20:39:29 +03:00
if ( offset )
critical_dmesgln ( " KUBSAN: assumption of {:p} byte alignment (with offset of {:p} byte) for pointer {:p} of type {} failed " , alignment , offset , pointer , data . type . name ( ) ) ;
else
critical_dmesgln ( " KUBSAN: assumption of {:p} byte alignment for pointer {:p} of type {} failed " , alignment , pointer , data . type . name ( ) ) ;
2021-05-02 16:29:44 +03:00
2021-02-11 22:58:01 +03:00
print_location ( data . location ) ;
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_builtin_unreachable ( UnreachableData const & ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_builtin_unreachable ( UnreachableData const & data )
2021-02-11 22:58:01 +03:00
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: execution reached an unreachable program point " ) ;
2021-02-11 22:58:01 +03:00
print_location ( data . location ) ;
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_missing_return ( UnreachableData const & ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_missing_return ( UnreachableData const & data )
2021-02-11 22:58:01 +03:00
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: execution reached the end of a value-returning function without returning a value " ) ;
2021-02-11 22:58:01 +03:00
print_location ( data . location ) ;
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_implicit_conversion ( ImplicitConversionData const & , ValueHandle , ValueHandle ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_implicit_conversion ( ImplicitConversionData const & data , ValueHandle , ValueHandle )
2021-02-11 22:58:01 +03:00
{
2022-04-01 20:58:27 +03:00
char const * src_signed = data . from_type . is_signed ( ) ? " " : " un " ;
char const * dst_signed = data . to_type . is_signed ( ) ? " " : " un " ;
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: implicit conversion from type {} ({}-bit, {}signed) to type {} ({}-bit, {}signed) " , data . from_type . name ( ) , data . from_type . bit_width ( ) , src_signed , data . to_type . name ( ) , data . to_type . bit_width ( ) , dst_signed ) ;
2021-02-11 22:58:01 +03:00
print_location ( data . location ) ;
}
2021-04-29 15:54:15 +03:00
void __ubsan_handle_invalid_builtin ( const InvalidBuiltinData ) __attribute__ ( ( used ) ) ;
2021-02-11 22:58:01 +03:00
void __ubsan_handle_invalid_builtin ( const InvalidBuiltinData data )
{
2021-12-19 20:39:29 +03:00
critical_dmesgln ( " KUBSAN: passing invalid argument " ) ;
2021-02-11 22:58:01 +03:00
print_location ( data . location ) ;
}
2022-04-01 20:58:27 +03:00
void __ubsan_handle_pointer_overflow ( PointerOverflowData const & , ValueHandle , ValueHandle ) __attribute__ ( ( used ) ) ;
void __ubsan_handle_pointer_overflow ( PointerOverflowData const & data , ValueHandle base , ValueHandle result )
2021-02-11 22:58:01 +03:00
{
2021-12-19 20:39:29 +03:00
if ( base = = 0 & & result = = 0 )
critical_dmesgln ( " KUBSAN: applied zero offset to nullptr " ) ;
else if ( base = = 0 & & result ! = 0 )
critical_dmesgln ( " KUBSAN: applied non-zero offset {:p} to nullptr " , result ) ;
else if ( base ! = 0 & & result = = 0 )
critical_dmesgln ( " KUBSAN: applying non-zero offset to non-null pointer {:p} produced null pointer " , base ) ;
else
critical_dmesgln ( " KUBSAN: addition of unsigned offset to {:p} overflowed to {:p} " , base , result ) ;
2021-02-11 22:58:01 +03:00
print_location ( data . location ) ;
}
2021-02-05 21:44:26 +03:00
}