kernel: add ubsan bindings, fix some UB reported by it

This commit is contained in:
Matheus
2024-12-31 11:20:27 -03:00
parent 4ee5fa42ae
commit 6245a3d19f
11 changed files with 348 additions and 90 deletions
+3 -3
View File
@@ -4,12 +4,12 @@
#include <uacpi/kernel_api.h>
static volatile struct limine_rsdp_request rsdpreq = {
static volatile struct limine_rsdp_request rsdp_request = {
.id = LIMINE_RSDP_REQUEST,
.revision = 0
};
uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *outrsdp) {
*outrsdp = (uintptr_t)FROM_HHDM(rsdpreq.response->address);
uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *rsdp_out) {
*rsdp_out = (uintptr_t)FROM_HHDM(rsdp_request.response->address);
return UACPI_STATUS_OK;
}
+40 -40
View File
@@ -12,7 +12,7 @@
#include <uacpi/acpi.h>
#define IOAPIC_REG_ID 0
#define IOAPIC_REG_ENTRYCOUNT 1
#define IOAPIC_REG_ENTRY_COUNT 1
#define IOAPIC_REG_PRIORITY 2
#define IOAPIC_REG_ENTRY 0x10
@@ -28,7 +28,7 @@
#define APIC_LVT_LINT0 0x350
#define APIC_LVT_LINT1 0x360
#define APIC_LVT_ERROR 0x370
#define APIC_TIMER_INITIALCOUNT 0x380
#define APIC_TIMER_INITIAL_COUNT 0x380
#define APIC_TIMER_COUNT 0x390
#define APIC_TIMER_DIVIDE 0x3E0
@@ -39,22 +39,22 @@ typedef struct {
void *addr;
int base;
int top;
} ioapicdesc_t;
} ioapic_desc_t;
static ioapicdesc_t *ioapics;
static ioapic_desc_t *ioapics;
static struct acpi_madt *madt;
static struct acpi_entry_hdr *liststart;
static struct acpi_entry_hdr *listend;
static void *lapicaddr;
static struct acpi_entry_hdr *list_start;
static struct acpi_entry_hdr *list_end;
static void *lapic_address;
static size_t overridecount;
static size_t iocount;
static size_t lapiccount;
static size_t lapicnmicount;
static size_t override_count;
static size_t io_count;
static size_t lapic_count;
static size_t lapic_nmi_count;
static ioapicdesc_t *ioapicfromgsi(int gsi) {
for (int i = 0; i < iocount; ++i) {
static ioapic_desc_t *ioapicfromgsi(int gsi) {
for (int i = 0; i < io_count; ++i) {
if (ioapics[i].base <= gsi && ioapics[i].top > gsi)
return &ioapics[i];
}
@@ -67,9 +67,9 @@ static inline struct acpi_entry_hdr *getnext(struct acpi_entry_hdr *header) {
}
static inline void *getentry(int type, int n) {
struct acpi_entry_hdr *entry = liststart;
struct acpi_entry_hdr *entry = list_start;
while (entry < listend) {
while (entry < list_end) {
if (entry->type == type) {
if (n-- == 0)
return entry;
@@ -81,10 +81,10 @@ static inline void *getentry(int type, int n) {
}
static int getcount(int type) {
struct acpi_entry_hdr *entry = liststart;
struct acpi_entry_hdr *entry = list_start;
int count = 0;
while (entry < listend) {
while (entry < list_end) {
if (entry->type == type)
++count;
entry = getnext(entry);
@@ -94,12 +94,12 @@ static int getcount(int type) {
}
static inline void writelapic(int reg, uint32_t v) {
volatile uint32_t *ptr = (void *)((uintptr_t)lapicaddr + reg);
volatile uint32_t *ptr = (void *)((uintptr_t)lapic_address + reg);
*ptr = v;
}
static inline uint32_t readlapic(int reg) {
volatile uint32_t *ptr = (void *)((uintptr_t)lapicaddr + reg);
volatile uint32_t *ptr = (void *)((uintptr_t)lapic_address + reg);
return *ptr;
}
@@ -131,7 +131,7 @@ void arch_ioapic_setirq(uint8_t irq, uint8_t vector, uint8_t proc, bool masked)
// default settings for ISA irqs
uint8_t polarity = 1; // active high
uint8_t trigger = 0; // edge triggered
for (uintmax_t i = 0; i < overridecount; ++i) {
for (uintmax_t i = 0; i < override_count; ++i) {
struct acpi_madt_interrupt_source_override *override = getentry(ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE, i);
if (override->source != irq)
continue;
@@ -142,7 +142,7 @@ void arch_ioapic_setirq(uint8_t irq, uint8_t vector, uint8_t proc, bool masked)
break;
}
ioapicdesc_t* ioapic = ioapicfromgsi(irq);
ioapic_desc_t* ioapic = ioapicfromgsi(irq);
__assert(ioapic);
irq = irq - ioapic->base;
writeiored(ioapic->addr, irq, vector, 0, 0, polarity, trigger, masked ? 1 : 0, proc);
@@ -170,7 +170,7 @@ void arch_apic_initap() {
// get the acpi id for the local nmi sources
for (size_t i = 0; i < lapiccount; ++i) {
for (size_t i = 0; i < lapic_count; ++i) {
struct acpi_madt_lapic *current = getentry(ACPI_MADT_ENTRY_TYPE_LAPIC, i);
if (current_cpu()->id == current->id) {
current_cpu()->acpiid = current->uid;
@@ -181,7 +181,7 @@ void arch_apic_initap() {
isr_t *nmiisr = interrupt_allocate(nmi, NULL, IPL_MAX); // MAX IPL because NMI
__assert(nmiisr);
for (size_t i = 0; i < lapicnmicount; ++i) {
for (size_t i = 0; i < lapic_nmi_count; ++i) {
struct acpi_madt_lapic_nmi* current = getentry(ACPI_MADT_ENTRY_TYPE_LAPIC_NMI, i);
if (current->uid == current_cpu()->acpiid || current->uid == 0xff)
writelapic(APIC_LVT_LINT0 + 0x10 * current->lint, (nmiisr->id & 0xff) | LVT_DELIVERY_NMI | (current->flags << 12));
@@ -194,16 +194,16 @@ void arch_apic_eoi() {
static time_t stoptimer(timer_t *) {
time_t remaining = readlapic(APIC_TIMER_COUNT);
time_t initial = readlapic(APIC_TIMER_INITIALCOUNT);
time_t initial = readlapic(APIC_TIMER_INITIAL_COUNT);
writelapic(APIC_TIMER_INITIALCOUNT, 0);
writelapic(APIC_TIMER_INITIAL_COUNT, 0);
return initial - remaining;
}
static time_t time_passed(timer_t *) {
time_t remaining = readlapic(APIC_TIMER_COUNT);
time_t initial = readlapic(APIC_TIMER_INITIALCOUNT);
time_t initial = readlapic(APIC_TIMER_INITIAL_COUNT);
return initial - remaining;
}
@@ -213,7 +213,7 @@ static void timerisr(isr_t *isr, context_t *context) {
}
static void armtimer(timer_t *, time_t ticks) {
writelapic(APIC_TIMER_INITIALCOUNT, ticks);
writelapic(APIC_TIMER_INITIAL_COUNT, ticks);
}
void arch_apic_timerinit() {
@@ -223,13 +223,13 @@ void arch_apic_timerinit() {
writelapic(APIC_TIMER_DIVIDE, 11);
writelapic(APIC_TIMER_INITIALCOUNT, 0xffffffff);
writelapic(APIC_TIMER_INITIAL_COUNT, 0xffffffff);
timekeeper_wait_us(50000);
time_t ticksperus = (0xffffffff - readlapic(APIC_TIMER_COUNT)) / 50000;
writelapic(APIC_TIMER_INITIALCOUNT, 0);
writelapic(APIC_TIMER_INITIAL_COUNT, 0);
printf("cpu%lu: local apic timer calibrated at %lu ticks per us. ISR vector %lu\n", current_cpu()->id, ticksperus, vec);
@@ -252,13 +252,13 @@ void arch_apic_init() {
__assert(ret == UACPI_STATUS_OK);
madt = tbl.ptr;
liststart = (void *)((uintptr_t)madt + sizeof(struct acpi_madt));
listend = (void *)((uintptr_t)madt + madt->hdr.length);
list_start = (void *)((uintptr_t)madt + sizeof(struct acpi_madt));
list_end = (void *)((uintptr_t)madt + madt->hdr.length);
overridecount = getcount(ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE);
iocount = getcount(ACPI_MADT_ENTRY_TYPE_IOAPIC);
lapiccount = getcount(ACPI_MADT_ENTRY_TYPE_LAPIC);
lapicnmicount = getcount(ACPI_MADT_ENTRY_TYPE_LAPIC_NMI);
override_count = getcount(ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE);
io_count = getcount(ACPI_MADT_ENTRY_TYPE_IOAPIC);
lapic_count = getcount(ACPI_MADT_ENTRY_TYPE_LAPIC);
lapic_nmi_count = getcount(ACPI_MADT_ENTRY_TYPE_LAPIC_NMI);
// map LAPIC to virtual memory
@@ -269,22 +269,22 @@ void arch_apic_init() {
if (lapic64)
printf("\e[94mUsing 64 bit override for the local APIC address\n\e[0m");
lapicaddr = vmm_map(NULL, PAGE_SIZE, VMM_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, paddr);
__assert(lapicaddr);
lapic_address = vmm_map(NULL, PAGE_SIZE, VMM_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, paddr);
__assert(lapic_address);
// map I/O apics to memory
ioapics = alloc(sizeof(ioapicdesc_t) * iocount);
ioapics = alloc(sizeof(ioapic_desc_t) * io_count);
__assert(ioapics);
for (int i = 0; i < iocount; ++i) {
for (int i = 0; i < io_count; ++i) {
struct acpi_madt_ioapic *entry = getentry(ACPI_MADT_ENTRY_TYPE_IOAPIC, i);
__assert((entry->address % PAGE_SIZE) == 0);
ioapics[i].addr = vmm_map(NULL, PAGE_SIZE, VMM_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, (void *)(uint64_t)entry->address);
__assert(ioapics[i].addr);
ioapics[i].base = entry->gsi_base;
ioapics[i].top = ioapics[i].base + ((readioapic(ioapics[i].addr, IOAPIC_REG_ENTRYCOUNT) >> 16) & 0xff) + 1;
ioapics[i].top = ioapics[i].base + ((readioapic(ioapics[i].addr, IOAPIC_REG_ENTRY_COUNT) >> 16) & 0xff) + 1;
printf("ioapic%lu: addr %p base %lu top %lu\n", i, entry->address, entry->gsi_base, ioapics[i].top);
for (int j = ioapics[i].base; j < ioapics[i].top; ++j)
writeiored(ioapics[i].addr, j - ioapics[i].base, 0xfe, 0, 0, 0, 0, 1, 0);
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef _TOPOLOGY_H
#define _TOPOLOGY_H
#define TOPOLOGY_MAKE_ID(depth, id) ((depth << 16) | id)
#define TOPOLOGY_MAKE_ID(depth, id) (((depth & 0xfffflu) << 16) | id)
#include <arch/cpu.h>
+1 -1
View File
@@ -7,7 +7,7 @@ size_t strlen(const char *str);
char *strcpy(char *dest, const char *src);
char *strcat(char *dest, const char *str);
void *memcpy(void *dest, const void *src, size_t size);
void *memset(void *dest, unsigned long what, size_t size);
void *memset(void *dest, int what, size_t size);
int strcmp(const char *a, const char *b);
int strncmp(const char *a, const char *b, size_t c);
int memcmp(const void *a, const void *b, size_t s);
+8 -6
View File
@@ -12,6 +12,11 @@ uint16_t pci_read16(int bus, int device, int function, uint32_t offset) {
return (pci_archread32(bus, device, function, offset) >> ((offset & 0b11) * 8)) & 0xffff;
}
uint32_t pci_read32(int bus, int device, int function, uint32_t offset) {
return pci_archread32(bus, device, function, offset);
}
void pci_write8(int bus, int device, int function, uint32_t offset, uint8_t v) {
uint32_t old = pci_archread32(bus, device, function, offset);
int bitoffset = 8 * (offset & 0b11);
@@ -23,19 +28,16 @@ void pci_write8(int bus, int device, int function, uint32_t offset, uint8_t v) {
void pci_write16(int bus, int device, int function, uint32_t offset, uint16_t v) {
uint32_t old = pci_archread32(bus, device, function, offset);
int bitoffset = 8 * (offset & 0b11);
old &= ~(0xffff << bitoffset);
old |= v << bitoffset;
old &= ~(0xfffflu << bitoffset);
old |= (uint32_t)v << bitoffset;
pci_archwrite32(bus, device, function, offset, old);
}
uint32_t pci_read32(int bus, int device, int function, uint32_t offset) {
return pci_archread32(bus, device, function, offset);
}
void pci_write32(int bus, int device, int function, uint32_t offset, uint32_t value) {
pci_archwrite32(bus, device, function, offset, value);
}
int pci_getcapoffset(pcienum_t *e, int cap, int n) {
if ((PCI_READ16(e, PCI_CONFIG_STATUS) & PCI_STATUS_HASCAP) == 0)
return 0;
+1 -1
View File
@@ -30,7 +30,7 @@ static int maxseek(int minor, size_t *max) {
static long current = 0xdeadbeefbadc0ffe;
static uint8_t getrand8() {
__attribute__((no_sanitize("undefined"))) static uint8_t getrand8() {
current += timekeeper_timefromboot().ns * timekeeper_timefromboot().s - timekeeper_time().ns * timekeeper_time().s + timekeeper_time().s;
return current & 0xff;
}
+1 -1
View File
@@ -16,7 +16,7 @@ void *memcpy(void *d, const void *s, size_t c) {
return d;
}
void *memset(void *ptr, unsigned long value, size_t num) {
void *memset(void *ptr, int value, size_t num) {
#ifdef __x86_64__
asm volatile ("rep stosb" : : "D"(ptr), "a"(value), "c"(num) : "memory");
#else
+252
View File
@@ -0,0 +1,252 @@
#include <stdint.h>
#include <logging.h>
/*
typedefs and some other bits taken from https://git.thenest.dev/wux/elysium-os/-/blob/5.0/kernel/src/ubsan.c
BSD 3-Clause License
Copyright (c) 2024, ImWuX
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
typedef struct {
const char *filename;
uint32_t line;
uint32_t column;
} source_location_t;
typedef struct {
uint16_t kind;
uint16_t info;
char name[];
} type_descriptor_t;
typedef struct {
source_location_t location;
} data_only_location_t;
typedef struct {
source_location_t location;
type_descriptor_t *type;
} data_location_type_t;
typedef struct {
source_location_t location;
type_descriptor_t *type;
} data_load_invalid_value_t;
typedef struct {
source_location_t location;
source_location_t attr_location;
int arg_index;
} data_nonnull_arg_t;
typedef struct {
source_location_t location;
type_descriptor_t *lhs_type;
type_descriptor_t *rhs_type;
} data_shift_out_of_bounds_t;
typedef struct {
source_location_t location;
type_descriptor_t *array_type;
type_descriptor_t *index_type;
} data_out_of_bounds_t;
typedef struct {
source_location_t location;
type_descriptor_t *type;
uint8_t alignment;
uint8_t type_check_kind;
} data_type_mismatch_t;
typedef struct {
source_location_t location;
source_location_t assumption_location;
type_descriptor_t *type;
} data_alignment_assumption_t;
typedef struct {
source_location_t location;
type_descriptor_t *from_type;
type_descriptor_t *to_type;
uint8_t kind;
} data_implicit_conversion_t;
typedef struct {
source_location_t location;
uint8_t kind;
} data_invalid_builtin_t;
const char *kind_to_type(uint16_t kind) {
const char* type;
switch (kind) {
case 0: type = "integer"; break;
case 1: type = "float"; break;
default: type = "unknown"; break;
}
return type;
}
unsigned int info_to_bits(uint16_t info) {
return 1 << (info >> 1);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_load_invalid_value(data_load_invalid_value_t *data, uintptr_t value) {
printf("\e[93mubsan: load_invalid_value @ %s:%u:%u {value: %#lx}\e[0m\n", data->location.filename, data->location.line, data->location.column, value);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_nonnull_arg(data_nonnull_arg_t *data) {
printf("\e[93mubsan: handle_nonnull_arg @ %s:%u:%u {arg_index: %i}\e[0m\n", data->location.filename, data->location.line, data->location.column, data->arg_index);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_nullability_arg(data_nonnull_arg_t *data) {
printf("\e[93mubsan: nullability_arg @ %s:%u:%u {arg_index: %i}\e[0m\n", data->location.filename, data->location.line, data->location.column, data->arg_index);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_nonnull_return_v1(data_only_location_t *data [[maybe_unused]], source_location_t *location) {
printf("\e[93mubsan: nonnull_return @ %s:%u:%u\e[0m\n", location->filename, location->line, location->column);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_nullability_return_v1(data_only_location_t *data [[maybe_unused]], source_location_t *location) {
printf("\e[93mubsan: nullability_return @ %s:%u:%u\e[0m\n", location->filename, location->line, location->column);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_vla_bound_not_positive(data_location_type_t *data, uintptr_t bound) {
printf("\e[93mubsan: vla_bound_not_positive @ %s:%u:%u {bound: %#lx, type: %u-bit %s %s}\e[0m\n",
data->location.filename, data->location.line, data->location.column, bound, info_to_bits(data->type->info), kind_to_type(data->type->kind), data->type->name
);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_add_overflow(data_location_type_t *data, uintptr_t lhs, uintptr_t rhs) {
printf("\e[93mubsan: add_overflow @ %s:%u:%u {lhs: %#lx, rhs: %#lx, type: %u-bit %s %s}\e[0m\n",
data->location.filename, data->location.line, data->location.column, lhs, rhs, info_to_bits(data->type->info), kind_to_type(data->type->kind), data->type->name
);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_sub_overflow(data_location_type_t *data, uintptr_t lhs, uintptr_t rhs) {
printf("\e[93mubsan: sub_overflow @ %s:%u:%u {lhs: %#lx, rhs: %#lx, type: %u-bit %s %s}\e[0m\n",
data->location.filename, data->location.line, data->location.column, lhs, rhs, info_to_bits(data->type->info), kind_to_type(data->type->kind), data->type->name
);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_mul_overflow(data_location_type_t *data, uintptr_t lhs, uintptr_t rhs) {
printf("\e[93mubsan: mul_overflow @ %s:%u:%u {lhs: %#lx, rhs: %#lx, type: %u-bit %s %s}\e[0m\n",
data->location.filename, data->location.line, data->location.column, lhs, rhs, info_to_bits(data->type->info), kind_to_type(data->type->kind), data->type->name
);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_divrem_overflow(data_location_type_t *data, uintptr_t lhs, uintptr_t rhs) {
printf("\e[93mubsan: divrem_overflow @ %s:%u:%u {lhs: %#lx, rhs: %#lx, type: %u-bit %s %s}\e[0m\n",
data->location.filename, data->location.line, data->location.column, lhs, rhs, info_to_bits(data->type->info), kind_to_type(data->type->kind), data->type->name
);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_negate_overflow(data_location_type_t *data, uintptr_t old) {
printf("\e[93mubsan: negate_overflow @ %s:%u:%u {old: %#lx, type: %u-bit %s %s}\e[0m\n",
data->location.filename, data->location.line, data->location.column, old, info_to_bits(data->type->info), kind_to_type(data->type->kind), data->type->name
);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_shift_out_of_bounds(data_shift_out_of_bounds_t *data, uintptr_t lhs, uintptr_t rhs) {
printf("\e[93mubsan: shift_out_of_bounds @ %s:%u:%u {lhs: %#lx, rhs: %#lx, rhs_type: %u-bit %s %s, lhs_type: %u-bit %s %s}\e[0m\n",
data->location.filename, data->location.line, data->location.column, lhs, rhs,
info_to_bits(data->rhs_type->info), kind_to_type(data->rhs_type->kind), data->rhs_type->name,
info_to_bits(data->lhs_type->info), kind_to_type(data->lhs_type->kind), data->lhs_type->name
);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_out_of_bounds(data_out_of_bounds_t *data, uint64_t index) {
printf("\e[93mubsan: out_of_bounds @ %s:%u:%u {index: %#lx, array_type: %u-bit %s %s, index_type: %u-bit %s %s}\e[0m\n",
data->location.filename, data->location.line, data->location.column, index,
info_to_bits(data->array_type->info), kind_to_type(data->array_type->kind), data->array_type->name,
info_to_bits(data->index_type->info), kind_to_type(data->index_type->kind), data->index_type->name
);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_type_mismatch_v1(data_type_mismatch_t *data, void *pointer) {
static const char *kind_strs[] = {
"load of",
"store to",
"reference binding to",
"member access within",
"member call on",
"constructor call on",
"downcast of",
"downcast of",
"upcast of",
"cast to virtual base of",
"nonnull binding to",
"dynamic operation on"
};
if(pointer == NULL) {
printf("\e[93mubsan: type_mismatch @ %s:%u:%u (%s NULL pointer of type %s)\e[0m\n",
data->location.filename, data->location.line, data->location.column, kind_strs[data->type_check_kind], data->type->name
);
} else if((1 << data->alignment) - 1) {
printf("\e[93mubsan: type_mismatch @ %s:%u:%u (%s misaligned address %#lx of type %s)\e[0m\n",
data->location.filename, data->location.line, data->location.column, kind_strs[data->type_check_kind], (uintptr_t) pointer, data->type->name
);
} else {
printf("\e[93mubsan: type_mismatch @ %s:%u:%u (%s address %#lx, not enough spce for type %s)\e[0m\n",
data->location.filename, data->location.line, data->location.column, kind_strs[data->type_check_kind], (uintptr_t) pointer, data->type->name
);
}
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_alignment_assumption(data_alignment_assumption_t *data, void *, void *, void *) {
printf("\e[93mubsan: alignment_assumption @ %s:%u:%u\e[0m\n", data->location.filename, data->location.line, data->location.column);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_implicit_conversion(data_implicit_conversion_t *data, void *, void *) {
printf("\e[93mubsan: implicit_conversion @ %s:%u:%u {from_type: %u-bit %s %s, to_type: %u-bit %s %s}\e[0m\n",
data->location.filename, data->location.line, data->location.column,
info_to_bits(data->from_type->info), kind_to_type(data->from_type->kind), data->from_type->name,
info_to_bits(data->to_type->info), kind_to_type(data->to_type->kind), data->to_type->name
);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_invalid_builtin(data_invalid_builtin_t *data) {
printf("\e[93mubsan: invalid_builtin @ %s:%u:%u\e[0m\n", data->location.filename, data->location.line, data->location.column);
}
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_pointer_overflow(data_only_location_t *data, void *, void *) {
printf("\e[93mubsan: pointer_overflow @ %s:%u:%u\e[0m\n", data->location.filename, data->location.line, data->location.column);
}
__attribute__((no_sanitize("undefined"))) __attribute__((noreturn)) void __ubsan_handle_builtin_unreachable(data_only_location_t *data) {
printf("\e[93mubsan: builtin_unreachable @ %s:%u:%u\e[0m\n", data->location.filename, data->location.line, data->location.column);
__assert(!"ubsan error");
}
__attribute__((no_sanitize("undefined"))) __attribute__((noreturn)) void __ubsan_handle_missing_return(data_only_location_t *data) {
printf("\e[93mubsan: missing_return @ %s:%u:%u\e[0m\n", data->location.filename, data->location.line, data->location.column);
__assert(!"ubsan error");
}
+1 -1
View File
@@ -35,7 +35,7 @@ static void dtor(scache_t *cache, void *obj) {
}
static scache_t *getcachefromsize(size_t size) {
if (size == 0)
if (size <= 1)
return caches[0];
size_t i = 64 - __builtin_clzll(size - 1);
+34 -34
View File
@@ -4,48 +4,48 @@
#include <limine.h>
#include <logging.h>
static volatile struct limine_kernel_file_request kfreq = {
static volatile struct limine_kernel_file_request kernel_file_request = {
.id = LIMINE_KERNEL_FILE_REQUEST,
.revision = 0
};
static hashtable_t pairtable;
static hashtable_t pair_table;
char *cmdline_get(char *key) {
void *v;
return hashtable_get(&pairtable, &v, key, strlen(key)) == 0 ? v : NULL;
return hashtable_get(&pair_table, &v, key, strlen(key)) == 0 ? v : NULL;
}
void cmdline_parse() {
__assert(hashtable_init(&pairtable, 16) == 0);
__assert(kfreq.response);
struct limine_file *kernelfile = kfreq.response->kernel_file;
__assert(kernelfile);
char *cmdline = kernelfile->cmdline;
__assert(hashtable_init(&pair_table, 16) == 0);
__assert(kernel_file_request.response);
struct limine_file *kernel_file = kernel_file_request.response->kernel_file;
__assert(kernel_file);
char *cmdline = kernel_file->cmdline;
__assert(cmdline);
size_t bufferlen = strlen(cmdline) + 1;
char buffer[bufferlen];
memset(buffer, 0, bufferlen);
char *cmdp = cmdline;
char *buffp = buffer;
size_t buffer_len = strlen(cmdline) + 1;
char buffer[buffer_len];
memset(buffer, 0, buffer_len);
char *cmdline_ptr = cmdline;
char *buffer_ptr = buffer;
bool doconvert = true;
bool do_convert = true;
while (*cmdp) {
char cmdchar = *cmdp++;
if (cmdchar == ' ' && doconvert)
*buffp++ = '\0';
else if (cmdchar == '"') {
doconvert = !doconvert;
--bufferlen;
while (*cmdline_ptr) {
char cmd_char = *cmdline_ptr++;
if (cmd_char == ' ' && do_convert)
*buffer_ptr++ = '\0';
else if (cmd_char == '"') {
do_convert = !do_convert;
--buffer_len;
} else
*buffp++ = cmdchar;
*buffer_ptr++ = cmd_char;
}
buffer[bufferlen] = '\0';
buffer[buffer_len - 1] = '\0';
int i = 0;
while (i < bufferlen) {
while (i < buffer_len) {
char *iterator = &buffer[i];
bool pair = false;
while (*iterator) {
@@ -56,22 +56,22 @@ void cmdline_parse() {
++iterator;
}
size_t keylen = strlen(&buffer[i]);
size_t key_len = strlen(&buffer[i]);
if (pair) {
char *valuep = &buffer[i + keylen + 1];
size_t valuelen = strlen(valuep);
char *value_ptr = &buffer[i + key_len + 1];
size_t value_len = strlen(value_ptr);
char *value = alloc(valuelen) + 1;
char *value = alloc(value_len) + 1;
__assert(value);
strcpy(value, valuep);
__assert(hashtable_set(&pairtable, value, &buffer[i], keylen, true) == 0);
i += valuelen + 1;
strcpy(value, value_ptr);
__assert(hashtable_set(&pair_table, value, &buffer[i], key_len, true) == 0);
i += value_len + 1;
} else {
char *value = alloc(keylen + 1);
char *value = alloc(key_len + 1);
__assert(value);
strcpy(value, &buffer[i]);
__assert(hashtable_set(&pairtable, value, &buffer[i], keylen, true) == 0);
__assert(hashtable_set(&pair_table, value, &buffer[i], key_len, true) == 0);
}
i += keylen + 1;
i += key_len + 1;
}
}
+6 -2
View File
@@ -422,6 +422,11 @@ void signal_signalproc(struct proc_t *proc, int signal) {
}
}
__attribute__((no_sanitize("undefined"))) static inline void set_siginfo_ucontext(context_t *context, void *stack) {
CTX_ARG1(context) = (uint64_t)&((sigframe_t *)stack)->siginfo;
CTX_ARG2(context) = (uint64_t)ARCH_SIGFRAME_GET_UCONTEXT_POINTER((sigframe_t *)stack);
}
// returns true if should retry check
bool signal_check(struct thread_t *thread, context_t *context, bool syscall, uint64_t syscallret, uint64_t syscallerrno, bool *need_context_switch) {
bool retry = false;
@@ -593,8 +598,7 @@ bool signal_check(struct thread_t *thread, context_t *context, bool syscall, uin
CTX_IP(context) = (uint64_t)action->address;
CTX_SP(context) = (uint64_t)stack;
CTX_ARG0(context) = signal;
CTX_ARG1(context) = (uint64_t)&((sigframe_t *)stack)->siginfo;
CTX_ARG2(context) = (uint64_t)ARCH_SIGFRAME_GET_UCONTEXT_POINTER((sigframe_t *)stack);
set_siginfo_ucontext(context, stack);
// reset handler if asked for
if (action->flags & SA_RESETHAND)