|
|
|
@@ -0,0 +1,160 @@
|
|
|
|
|
/*
|
|
|
|
|
* @author xamidev <xamidev@riseup.net>
|
|
|
|
|
* @brief Undefined behavior sanitization hooks
|
|
|
|
|
* @license GPL-3.0-only
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <security/ubsan.h>
|
|
|
|
|
#include <kernel.h>
|
|
|
|
|
#include <stddef.h>
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Hooks were inspired from the Sortix implementation:
|
|
|
|
|
* https://gitlab.com/sortix/sortix/-/blob/main/libc/ubsan/ubsan.c
|
|
|
|
|
*
|
|
|
|
|
* Not all hooks are implemented here.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
extern struct init_status init;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* __ubsan_handle_type_mismatch_v1 - Hook for UBSan
|
|
|
|
|
* @data_raw: pointer to error data
|
|
|
|
|
* @pointer_raw: faulty pointer
|
|
|
|
|
*
|
|
|
|
|
* This function is executed when the UBSan library detects
|
|
|
|
|
* following undefined behavior: type mismatch, null pointer
|
|
|
|
|
* access, and unaligned access. It halts the system and
|
|
|
|
|
* gives the location of the code that triggered it.
|
|
|
|
|
*/
|
|
|
|
|
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;
|
|
|
|
|
uintptr_t pointer = (uintptr_t)pointer_raw;
|
|
|
|
|
uintptr_t alignment = (uintptr_t)1UL << data->log_alignment;
|
|
|
|
|
const char* violation = "type mismatch";
|
|
|
|
|
if ( !pointer ) {
|
|
|
|
|
violation = "null pointer access";
|
|
|
|
|
}
|
|
|
|
|
else if ( alignment && (pointer & (alignment - 1)) ) {
|
|
|
|
|
violation = "unaligned access";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct ubsan_source_location* loc = &data->location;
|
|
|
|
|
|
|
|
|
|
DEBUG("\x1b[38;5;231mUBSan: %s (ptr=%p) at %s:%u:%u\x1b[0m", violation, pointer, loc->filename, loc->line, loc->column);
|
|
|
|
|
|
|
|
|
|
if (init.all) {
|
|
|
|
|
printf("\x1b[38;5;231mUBSan: %s (ptr=%p) at %s:%u:%u\x1b[0m\r\n", violation, pointer, loc->filename, loc->line, loc->column);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
panic(NULL, "Undefined Behavior Sanitization error");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* __ubsan_handle_pointer_overflow - Hook for UBSan
|
|
|
|
|
* @data_raw: pointer to error data
|
|
|
|
|
* @base_raw: base pointer
|
|
|
|
|
* @result_raw: pointer after faulty operation
|
|
|
|
|
*
|
|
|
|
|
* This function is executed when the UBSan library detects
|
|
|
|
|
* following undefined behavior: pointer overflow.
|
|
|
|
|
* It halts the system and gives the location of the code
|
|
|
|
|
* that triggered it.
|
|
|
|
|
*/
|
|
|
|
|
void __ubsan_handle_pointer_overflow(void* data_raw, void* base_raw, void* result_raw)
|
|
|
|
|
{
|
|
|
|
|
struct ubsan_pointer_overflow_data* data = (struct ubsan_pointer_overflow_data*) data_raw;
|
|
|
|
|
uintptr_t base = (uintptr_t)base_raw;
|
|
|
|
|
uintptr_t result = (uintptr_t)result_raw;
|
|
|
|
|
|
|
|
|
|
struct ubsan_source_location* loc = &data->location;
|
|
|
|
|
|
|
|
|
|
DEBUG("\x1b[38;5;231mUBSan: pointer overflow (base=%p, result=%p) at %s:%u:%u\x1b[0m", base, result, loc->filename, loc->line, loc->column);
|
|
|
|
|
|
|
|
|
|
if (init.all) {
|
|
|
|
|
printf("\x1b[38;5;231mUBSan: pointer overflow (base=%p, result=%p) at %s:%u:%u\x1b[0m", base, result, loc->filename, loc->line, loc->column);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
panic(NULL, "Undefined Behavior Sanitization error: pointer overflow");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* __ubsan_handle_shift_out_of_bounds - Hook for UBSan
|
|
|
|
|
* @data_raw: pointer to error data
|
|
|
|
|
* @lhs_raw: left hand side (value being shifted)
|
|
|
|
|
* @rhs_raw: right hand side (shift amount)
|
|
|
|
|
*
|
|
|
|
|
* This function is executed when the UBSan library detects
|
|
|
|
|
* following undefined behavior: shift out of bounds.
|
|
|
|
|
* It halts the system and gives the location of the code
|
|
|
|
|
* that triggered it.
|
|
|
|
|
*/
|
|
|
|
|
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;
|
|
|
|
|
uintptr_t lhs = (uintptr_t) lhs_raw;
|
|
|
|
|
uintptr_t rhs = (uintptr_t) rhs_raw;
|
|
|
|
|
|
|
|
|
|
struct ubsan_source_location* loc = &data->location;
|
|
|
|
|
|
|
|
|
|
DEBUG("\x1b[38;5;231mUBSan: shift out of bounds (lhs=%p, rhs=%p) at %s:%u:%u\x1b[0m", lhs, rhs, loc->filename, loc->line, loc->column);
|
|
|
|
|
|
|
|
|
|
if (init.all) {
|
|
|
|
|
printf("\x1b[38;5;231mUBSan: shift out of bounds (lhs=%p, rhs=%p) at %s:%u:%u\x1b[0m", lhs, rhs, loc->filename, loc->line, loc->column);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
panic(NULL, "Undefined Behavior Sanitization error: shift out of bounds");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* __ubsan_handle_load_invalid_value - Hook for UBSan
|
|
|
|
|
* @data_raw: pointer to error data
|
|
|
|
|
* @value_raw: value loaded
|
|
|
|
|
*
|
|
|
|
|
* This function is executed when the UBSan library detects
|
|
|
|
|
* following undefined behavior: invalid value load.
|
|
|
|
|
* It halts the system and gives the location of the code
|
|
|
|
|
* that triggered it.
|
|
|
|
|
*/
|
|
|
|
|
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;
|
|
|
|
|
uintptr_t value = (uintptr_t) value_raw;
|
|
|
|
|
|
|
|
|
|
struct ubsan_source_location* loc = &data->location;
|
|
|
|
|
|
|
|
|
|
DEBUG("\x1b[38;5;231mUBSan: invalid value load (value=%p) at %s:%u:%u\x1b[0m", value, loc->filename, loc->line, loc->column);
|
|
|
|
|
|
|
|
|
|
if (init.all) {
|
|
|
|
|
printf("\x1b[38;5;231mUBSan: invalid value load (value=%p) at %s:%u:%u\x1b[0m", value, loc->filename, loc->line, loc->column);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
panic(NULL, "Undefined Behavior Sanitization error: invalid value load");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* __ubsan_handle_out_of_bounds - Hook for UBSan
|
|
|
|
|
* @data_raw: pointer to error data
|
|
|
|
|
* @index_raw: out-of-bounds index in array
|
|
|
|
|
*
|
|
|
|
|
* This function is executed when the UBSan library detects
|
|
|
|
|
* following undefined behavior: access out of bounds.
|
|
|
|
|
* It halts the system and gives the location of the code
|
|
|
|
|
* that triggered it.
|
|
|
|
|
*/
|
|
|
|
|
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;
|
|
|
|
|
uintptr_t index = (uintptr_t) index_raw;
|
|
|
|
|
struct ubsan_source_location* loc = &data->location;
|
|
|
|
|
|
|
|
|
|
DEBUG("\x1b[38;5;231mUBSan: out of bounds (index=%p) at %s:%u:%u\x1b[0m", index, loc->filename, loc->line, loc->column);
|
|
|
|
|
|
|
|
|
|
if (init.all) {
|
|
|
|
|
printf("\x1b[38;5;231mUBSan: out of bounds (index=%p) at %s:%u:%u\x1b[0m", index, loc->filename, loc->line, loc->column);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
panic(NULL, "Undefined Behavior Sanitization error: out of bounds");
|
|
|
|
|
}
|