wip: today

This commit is contained in:
Matthew LeVan 2024-01-19 15:36:36 -05:00
parent 42f56a545a
commit 0d5e8b86aa
2 changed files with 50 additions and 25 deletions

View File

@ -37,12 +37,13 @@ fn main() {
.flag("-g3") .flag("-g3")
.flag("-Wall") .flag("-Wall")
.flag("-Wextra") .flag("-Wextra")
.flag("-Wgnu-pointer-arith")
.flag("-Wpointer-arith")
.flag("-Wpedantic") .flag("-Wpedantic")
.flag("-Wformat=2") .flag("-Wformat=2")
.flag("-Wno-unused-parameter") .flag("-Wno-unused-parameter")
.flag("-Wshadow") .flag("-Wshadow")
.flag("-Wwrite-strings") .flag("-Wwrite-strings")
.flag("-Wstrict-prototypes")
.flag("-Wold-style-definition") .flag("-Wold-style-definition")
.flag("-Wredundant-decls") .flag("-Wredundant-decls")
.flag("-Wnested-externs") .flag("-Wnested-externs")

View File

@ -14,26 +14,22 @@ static void *stack_p = NULL;
static void *alloc_p = NULL; static void *alloc_p = NULL;
typedef enum { typedef enum {
guard_weird = 0, // strange state guard_sound = 0, // job's done
guard_armor = 1, // mprotect failure guard_armor = 1, // mprotect
guard_spent = 2, // out of memory (bail:meme) guard_weird = 2, // strange state
guard_sound = 3 // job's done guard_spent = 3, // out of memory (bail:meme)
} guard_err; guard_erupt = 4, // sigint
} guard_err_t;
volatile sig_atomic_t guard_err = guard_sound;
guard_err _focus_guard(void *si_addr) { guard_err_t _focus_guard(void *si_addr) {
// Check for strange situations.
if (stack_p == NULL || alloc_p == NULL || si_addr == NULL) { if (stack_p == NULL || alloc_p == NULL || si_addr == NULL) {
return guard_weird; return guard_weird;
} }
// Install the guard page, if needed.
if (guard_p == NULL) {
guard_p = stack_p + ((alloc_p - stack_p) / 2);
if (mprotect(guard_p, GD_PAGESZ, PROT_NONE) == -1) {
return guard_armor;
}
}
// Re-center the guard page if the fault address falls within it. // Re-center the guard page if the fault address falls within it.
if (si_addr >= guard_p && si_addr < guard_p + GD_PAGESZ) { if (si_addr >= guard_p && si_addr < guard_p + GD_PAGESZ) {
// Unmark the old guard page. // Unmark the old guard page.
@ -44,6 +40,8 @@ guard_err _focus_guard(void *si_addr) {
// Place the new guard page in the center. // Place the new guard page in the center.
guard_p = stack_p + ((alloc_p - stack_p) / 2); guard_p = stack_p + ((alloc_p - stack_p) / 2);
// TODO: Ensure the guard_p is page-aligned.
// guard_p = (void *)((uintptr_t)guard_p & ~(GD_PAGESZ - 1));
if (guard_p != old_guard_pg) { if (guard_p != old_guard_pg) {
if (mprotect(guard_p, GD_PAGESZ, PROT_NONE) == -1) { if (mprotect(guard_p, GD_PAGESZ, PROT_NONE) == -1) {
return guard_armor; return guard_armor;
@ -56,35 +54,61 @@ guard_err _focus_guard(void *si_addr) {
return guard_sound; return guard_sound;
} }
void _sigsegv_handler(int sig, siginfo_t *si, void *unused) { void _signal_handler(int sig, siginfo_t *si, void *unused) {
_focus_guard(si->si_addr); switch (sig) {
case SIGSEGV:
guard_err = _focus_guard(si->si_addr);
break;
case SIGINT:
guard_err = guard_erupt;
break;
default:
break;
}
} }
int _register_handler() { guard_err_t _register_handler() {
guard_err_t err = guard_sound;
struct sigaction sa; struct sigaction sa;
sa.sa_flags = SA_SIGINFO; sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = _sigsegv_handler; sa.sa_sigaction = _signal_handler;
sigemptyset(&sa.sa_mask); sa.sa_mask = 0;
return sigaction(SIGSEGV, &sa, NULL); if (sigaction(SIGSEGV, &sa, NULL)) {
err = guard_weird;
}
return guard_err;
} }
void guard(void *(*f)(void *), void *arg, void **stack, void **alloc, void **ret) { void guard(void *(*f)(void *), void *arg, void **stack, void **alloc, void **ret) {
guard_err err; guard_err_t err;
stack_p = *stack; stack_p = *stack;
alloc_p = *alloc; alloc_p = *alloc;
if (_register_handler() == -1) { if (_register_handler() != guard_sound) {
err = guard_weird; err = guard_weird;
goto fail; goto fail;
} }
if (guard_p == NULL) {
guard_p = stack_p + ((alloc_p - stack_p) / 2);
if (mprotect(guard_p, GD_PAGESZ, PROT_NONE) == -1) {
err = guard_armor;
goto fail;
}
}
*ret = f(arg); *ret = f(arg);
if (guard_err != guard_sound) {
goto fail;
}
return; return;
fail: fail:
*ret = (void *) &err; *ret = (void *) &guard_err;
return; return;
} }