Undefined Behavior Sanitization

This commit is contained in:
2026-03-28 21:09:08 +01:00
parent 89259ec9b2
commit 3cd38f654c
5 changed files with 237 additions and 10 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ OBJFILES := $(patsubst $(SRC)/%.c, $(BUILDDIR)/%.o, $(SOURCES))
CC := x86_64-elf-gcc
CC_FLAGS=-Wall -Wextra -std=gnu99 -nostdlib -ffreestanding -fstack-protector -fno-omit-frame-pointer -fno-stack-check -fno-PIC -ffunction-sections -fdata-sections -mcmodel=kernel
CC_PROBLEMATIC_FLAGS=-Wno-unused-parameter -Wno-unused-variable
CC_PROBLEMATIC_FLAGS=-Wno-unused-parameter -Wno-unused-variable -fsanitize=undefined
LD := x86_64-elf-ld
+59
View File
@@ -0,0 +1,59 @@
/*
* @author xamidev <xamidev@riseup.net>
* @brief Undefined behavior sanitization hooks
* @license GPL-3.0-only
*/
#ifndef UBSAN_H
#define UBSAN_H
#include <stdint.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[];
};
struct ubsan_type_mismatch_v1_data
{
struct ubsan_source_location location;
struct ubsan_type_descriptor* type;
unsigned char log_alignment;
unsigned char type_check_kind;
};
struct ubsan_pointer_overflow_data
{
struct ubsan_source_location location;
};
struct ubsan_shift_out_of_bounds_data
{
struct ubsan_source_location location;
struct ubsan_type_descriptor* lhs_type;
struct ubsan_type_descriptor* rhs_type;
};
struct ubsan_invalid_value_data
{
struct ubsan_source_location location;
struct ubsan_type_descriptor* type;
};
struct ubsan_out_of_bounds_data
{
struct ubsan_source_location location;
struct ubsan_type_descriptor* array_type;
struct ubsan_type_descriptor* index_type;
};
#endif
-9
View File
@@ -85,15 +85,6 @@ void thing_main(void* arg)
extern uintptr_t kheap_start;
/* Stack Smashing Protection */
uint64_t __stack_chk_guard = STACK_CHK_GUARD;
void __stack_chk_fail(void)
{
panic(NULL, "SSP: Stask Smashing Detected!!! (very spicy)");
}
/*
* kmain - Kernel entry point
*
+17
View File
@@ -0,0 +1,17 @@
/*
* @author xamidev <xamidev@riseup.net>
* @brief Stack Smashing Protection feature
* @license GPL-3.0-only
*/
#include <config.h>
#include <stdint.h>
#include <kernel.h>
#include <stddef.h>
uint64_t __stack_chk_guard = STACK_CHK_GUARD;
void __stack_chk_fail(void)
{
panic(NULL, "SSP: Stask Smashing Detected!!! (very spicy)");
}
+160
View File
@@ -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");
}