more UBsan

This commit is contained in:
2026-03-28 21:50:19 +01:00
parent 3cd38f654c
commit 65371077d9
8 changed files with 184 additions and 12 deletions
+3 -1
View File
@@ -73,4 +73,6 @@ PepperOS wouldn't be possible without the following freely-licensed software:
- the [OSDev](https://osdev.org) wiki & forums - the [OSDev](https://osdev.org) wiki & forums
- Intel 64 and IA-32 Architectures Software Developer's Manual - Intel 64 and IA-32 Architectures Software Developer's Manual
- Documentation for the [GNU Compiler Collection](https://gcc.gnu.org/onlinedocs/gcc/) - Documentation for the [GNU Compiler Collection](https://gcc.gnu.org/onlinedocs/gcc/)
- dreamos82's [OSDev Notes](https://github.com/dreamportdev/Osdev-Notes/tree/master) - dreamos82's [OSDev Notes](https://github.com/dreamportdev/Osdev-Notes/tree/master)
- the [Sortix UBsan hook implementations](https://gitlab.com/sortix/sortix/-/blob/main/libc/ubsan/ubsan.c)
- the [CSC 395](https://curtsinger.cs.grinnell.edu/teaching/2022S/CSC395/kernel/) Kernel Development course from Grinnell College
+14
View File
@@ -0,0 +1,14 @@
/*
* @author xamidev <xamidev@riseup.net>
* @brief Boot routines
* @license GPL-3.0-only
*/
#ifndef BOOT_H
#define BOOT_H
#include <kernel.h>
void populate_boot_context(struct boot_context* boot_ctx);
#endif
+1 -1
View File
@@ -1,6 +1,6 @@
/* /*
* @author xamidev <xamidev@riseup.net> * @author xamidev <xamidev@riseup.net>
* @brief Global Descriptor Table (for legacy reasons) * @brief Global Descriptor Table
* @license GPL-3.0-only * @license GPL-3.0-only
*/ */
+7
View File
@@ -56,4 +56,11 @@ struct ubsan_out_of_bounds_data
struct ubsan_type_descriptor* index_type; struct ubsan_type_descriptor* index_type;
}; };
struct ubsan_overflow_data
{
struct ubsan_source_location location;
struct ubsan_type_descriptor* type;
};
#endif #endif
+14 -1
View File
@@ -9,7 +9,9 @@
* @license GPL-3.0-only * @license GPL-3.0-only
*/ */
#include <kernel.h>
#include <limine.h> #include <limine.h>
#include <stddef.h>
__attribute__((used, section(".limine_requests"))) __attribute__((used, section(".limine_requests")))
volatile struct limine_framebuffer_request framebuffer_request = { volatile struct limine_framebuffer_request framebuffer_request = {
@@ -45,4 +47,15 @@ __attribute__((used, section(".limine_requests_start")))
volatile LIMINE_REQUESTS_START_MARKER; volatile LIMINE_REQUESTS_START_MARKER;
__attribute__((used, section(".limine_requests_end"))) __attribute__((used, section(".limine_requests_end")))
volatile LIMINE_REQUESTS_END_MARKER; volatile LIMINE_REQUESTS_END_MARKER;
void populate_boot_context(struct boot_context* ctx)
{
// Populate boot context
// This stays valid only if the BOOTLOADER_RECLAIMABLE regions are preserved
ctx->fb = framebuffer_request.response ? framebuffer_request.response->framebuffers[0] : NULL;
ctx->mmap = memmap_request.response ? memmap_request.response : NULL;
ctx->hhdm = hhdm_request.response ? hhdm_request.response : NULL;
ctx->kaddr = kerneladdr_request.response ? kerneladdr_request.response : NULL;
ctx->bootdate = date_request.response ? date_request.response : NULL;
}
+10
View File
@@ -44,6 +44,7 @@ void pedicel_main(void* arg)
printf("\r\nYou are currently running the test kernel shell. This is not\r\n" printf("\r\nYou are currently running the test kernel shell. This is not\r\n"
"a fully-fledged shell like you'd find in a complete operating system,\r\n" "a fully-fledged shell like you'd find in a complete operating system,\r\n"
"but rather a toy to play around in the meantime.\r\n\r\n" "but rather a toy to play around in the meantime.\r\n\r\n"
"clear - clear the screen\r\n"
"panic - trigger a test panic\r\n" "panic - trigger a test panic\r\n"
"syscall - trigger int 0x80\r\n" "syscall - trigger int 0x80\r\n"
"pf - trigger a page fault\r\n" "pf - trigger a page fault\r\n"
@@ -52,6 +53,15 @@ void pedicel_main(void* arg)
continue; continue;
} }
if (strncmp(input_buf, "", 1) == 0) {
continue;
}
if (strncmp(input_buf, "clear", 5) == 0) {
printf("\x1b[2J\x1b[H");
continue;
}
if (strncmp(input_buf, "panic", 5) == 0) { if (strncmp(input_buf, "panic", 5) == 0) {
panic(NULL, "test panic"); panic(NULL, "test panic");
} }
+2 -9
View File
@@ -4,8 +4,6 @@
* @license GPL-3.0-only * @license GPL-3.0-only
*/ */
#include "arch/x86.h"
#include "time/date.h"
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <limine.h> #include <limine.h>
@@ -26,6 +24,7 @@
#include <io/term/flanterm.h> #include <io/term/flanterm.h>
#include <io/term/flanterm_backends/fb.h> #include <io/term/flanterm_backends/fb.h>
#include <arch/x86.h> #include <arch/x86.h>
#include <boot/boot.h>
// Limine version used // Limine version used
__attribute__((used, section(".limine_requests"))) __attribute__((used, section(".limine_requests")))
@@ -98,13 +97,7 @@ void kmain()
CLEAR_INTERRUPTS; CLEAR_INTERRUPTS;
if (!LIMINE_BASE_REVISION_SUPPORTED) hcf(); if (!LIMINE_BASE_REVISION_SUPPORTED) hcf();
// Populate boot context populate_boot_context(&boot_ctx);
// This stays valid only if the BOOTLOADER_RECLAIMABLE regions are preserved
boot_ctx.fb = framebuffer_request.response ? framebuffer_request.response->framebuffers[0] : NULL;
boot_ctx.mmap = memmap_request.response ? memmap_request.response : NULL;
boot_ctx.hhdm = hhdm_request.response ? hhdm_request.response : NULL;
boot_ctx.kaddr = kerneladdr_request.response ? kerneladdr_request.response : NULL;
boot_ctx.bootdate = date_request.response ? date_request.response : NULL;
term_init(); term_init();
serial_init(); serial_init();
+133
View File
@@ -158,3 +158,136 @@ void __ubsan_handle_out_of_bounds(void* data_raw, void* index_raw)
panic(NULL, "Undefined Behavior Sanitization error: out of bounds"); panic(NULL, "Undefined Behavior Sanitization error: out of bounds");
} }
/*
* __ubsan_handle_divrem_overflow - Hook for UBSan
* @data_raw: pointer to error data
* @lhs_raw: left hand side operator
* @rhs_raw: right hand side operator
*
* This function is executed when the UBSan library detects
* following undefined behavior: division remainder overflow.
* It halts the system and gives the location of the code
* that triggered it.
*/
void __ubsan_handle_divrem_overflow(void* data_raw, void* lhs_raw, void* rhs_raw)
{
struct ubsan_overflow_data* data = (struct ubsan_overflow_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: division remainder overflow (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: division remainder overflow (lhs=%p, rhs=%p) at %s:%u:%u\x1b[0m", lhs, rhs, loc->filename, loc->line, loc->column);
}
panic(NULL, "Undefined Behavior Sanitization error: division remainder overflow");
}
/*
* __ubsan_handle_sub_overflow - Hook for UBSan
* @data_raw: pointer to error data
* @lhs_raw: left hand side operator
* @rhs_raw: right hand side operator
*
* This function is executed when the UBSan library detects
* following undefined behavior: subtraction overflow.
* It halts the system and gives the location of the code
* that triggered it.
*/
void __ubsan_handle_sub_overflow(void* data_raw, void* lhs_raw, void* rhs_raw)
{
struct ubsan_overflow_data* data = (struct ubsan_overflow_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: subtraction overflow (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: subtraction overflow (lhs=%p, rhs=%p) at %s:%u:%u\x1b[0m", lhs, rhs, loc->filename, loc->line, loc->column);
}
panic(NULL, "Undefined Behavior Sanitization error: subtraction overflow");
}
/*
* __ubsan_handle_add_overflow - Hook for UBSan
* @data_raw: pointer to error data
* @lhs_raw: left hand side operator
* @rhs_raw: right hand side operator
*
* This function is executed when the UBSan library detects
* following undefined behavior: addition overflow.
* It halts the system and gives the location of the code
* that triggered it.
*/
void __ubsan_handle_add_overflow(void* data_raw, void* lhs_raw, void* rhs_raw)
{
struct ubsan_overflow_data* data = (struct ubsan_overflow_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: addition overflow (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: addition overflow (lhs=%p, rhs=%p) at %s:%u:%u\x1b[0m", lhs, rhs, loc->filename, loc->line, loc->column);
}
panic(NULL, "Undefined Behavior Sanitization error: addition overflow");
}
/*
* __ubsan_handle_mul_overflow - Hook for UBSan
* @data_raw: pointer to error data
* @lhs_raw: left hand side operator
* @rhs_raw: right hand side operator
*
* This function is executed when the UBSan library detects
* following undefined behavior: multiplication overflow.
* It halts the system and gives the location of the code
* that triggered it.
*/
void __ubsan_handle_mul_overflow(void* data_raw, void* lhs_raw, void* rhs_raw)
{
struct ubsan_overflow_data* data = (struct ubsan_overflow_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: multiplication overflow (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: multiplication overflow (lhs=%p, rhs=%p) at %s:%u:%u\x1b[0m", lhs, rhs, loc->filename, loc->line, loc->column);
}
panic(NULL, "Undefined Behavior Sanitization error: multiplication overflow");
}
/*
* __ubsan_handle_negate_overflow - Hook for UBSan
* @data_raw: pointer to error data
* @old_value_raw: value before overflow
*
* This function is executed when the UBSan library detects
* following undefined behavior: negation overflow.
* It halts the system and gives the location of the code
* that triggered it.
*/
void __ubsan_handle_negate_overflow(void* data_raw, void* old_value_raw)
{
struct ubsan_overflow_data* data = (struct ubsan_overflow_data*) data_raw;
uintptr_t old_value = (uintptr_t) old_value_raw;
struct ubsan_source_location* loc = &data->location;
DEBUG("\x1b[38;5;231mUBSan: negation overflow (old_value=%p) at %s:%u:%u\x1b[0m", old_value, loc->filename, loc->line, loc->column);
if (init.all) {
printf("\x1b[38;5;231mUBSan: negation overflow (old_value=%p) at %s:%u:%u\x1b[0m", old_value, loc->filename, loc->line, loc->column);
}
panic(NULL, "Undefined Behavior Sanitization error: negation overflow");
}