mirror of
https://github.com/urbit/ares.git
synced 2024-11-23 00:25:49 +03:00
wip: friday
This commit is contained in:
parent
0d5e8b86aa
commit
f7fcffc429
@ -37,17 +37,17 @@ fn main() {
|
|||||||
.flag("-g3")
|
.flag("-g3")
|
||||||
.flag("-Wall")
|
.flag("-Wall")
|
||||||
.flag("-Wextra")
|
.flag("-Wextra")
|
||||||
.flag("-Wgnu-pointer-arith")
|
|
||||||
.flag("-Wpointer-arith")
|
|
||||||
.flag("-Wpedantic")
|
|
||||||
.flag("-Wformat=2")
|
.flag("-Wformat=2")
|
||||||
.flag("-Wno-unused-parameter")
|
.flag("-Wmissing-include-dirs")
|
||||||
|
.flag("-Wnested-externs")
|
||||||
|
.flag("-Wold-style-definition")
|
||||||
|
.flag("-Wpedantic")
|
||||||
|
.flag("-Wredundant-decls")
|
||||||
.flag("-Wshadow")
|
.flag("-Wshadow")
|
||||||
.flag("-Wwrite-strings")
|
.flag("-Wwrite-strings")
|
||||||
.flag("-Wold-style-definition")
|
.flag("-Wno-unused-parameter")
|
||||||
.flag("-Wredundant-decls")
|
.flag("-Wno-pointer-arith")
|
||||||
.flag("-Wnested-externs")
|
.flag("-Wno-strict-prototypes")
|
||||||
.flag("-Wmissing-include-dirs")
|
|
||||||
.try_compile("guard");
|
.try_compile("guard");
|
||||||
|
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
#include "guard.h"
|
#include "guard.h"
|
||||||
|
|
||||||
|
|
||||||
#define GD_PAGESZ 16384
|
#define GD_PAGEBITS 14ULL
|
||||||
|
#define GD_PAGESIZE (1ULL << GD_PAGEBITS) /* 16K */
|
||||||
|
|
||||||
static void *guard_p = NULL;
|
static void *guard_p = NULL;
|
||||||
static void *stack_p = NULL;
|
static void *stack_p = NULL;
|
||||||
@ -19,45 +20,60 @@ typedef enum {
|
|||||||
guard_weird = 2, // strange state
|
guard_weird = 2, // strange state
|
||||||
guard_spent = 3, // out of memory (bail:meme)
|
guard_spent = 3, // out of memory (bail:meme)
|
||||||
guard_erupt = 4, // sigint
|
guard_erupt = 4, // sigint
|
||||||
} guard_err_t;
|
} guard_error;
|
||||||
|
|
||||||
volatile sig_atomic_t guard_err = guard_sound;
|
volatile sig_atomic_t guard_err = guard_sound;
|
||||||
|
|
||||||
|
|
||||||
guard_err_t _focus_guard(void *si_addr) {
|
// Center the guard page.
|
||||||
|
guard_error _focus_guard() {
|
||||||
// Check for strange situations.
|
// Check for strange situations.
|
||||||
if (stack_p == NULL || alloc_p == NULL || si_addr == NULL) {
|
if (stack_p == NULL || alloc_p == NULL) {
|
||||||
return guard_weird;
|
return guard_weird;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-center the guard page if the fault address falls within it.
|
|
||||||
if (si_addr >= guard_p && si_addr < guard_p + GD_PAGESZ) {
|
|
||||||
// Unmark the old guard page.
|
// Unmark the old guard page.
|
||||||
void *old_guard_pg = guard_p;
|
void *old_guard_p = guard_p;
|
||||||
if (mprotect(old_guard_pg, GD_PAGESZ, PROT_READ | PROT_WRITE) == -1) {
|
if (mprotect(old_guard_p, GD_PAGESIZE, PROT_READ | PROT_WRITE) == -1) {
|
||||||
return guard_armor;
|
return guard_armor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Place the new guard page in the center.
|
// Place the new guard page in the center.
|
||||||
|
if (stack_p > alloc_p) {
|
||||||
|
guard_p = stack_p - ((stack_p - alloc_p) / 2);
|
||||||
|
}
|
||||||
|
else if (stack_p < alloc_p) {
|
||||||
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));
|
else {
|
||||||
if (guard_p != old_guard_pg) {
|
return guard_weird;
|
||||||
if (mprotect(guard_p, GD_PAGESZ, PROT_NONE) == -1) {
|
}
|
||||||
|
guard_p = (void *)((uintptr_t)guard_p & ~(GD_PAGESIZE - 1));
|
||||||
|
|
||||||
|
// Mark the new guard page.
|
||||||
|
if (guard_p != old_guard_p) {
|
||||||
|
if (mprotect(guard_p, GD_PAGESIZE, PROT_NONE) == -1) {
|
||||||
return guard_armor;
|
return guard_armor;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return guard_spent;
|
return guard_spent;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return guard_sound;
|
return guard_sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guard_error _slash_guard(void *si_addr) {
|
||||||
|
if (si_addr >= guard_p && si_addr < guard_p + GD_PAGESIZE) {
|
||||||
|
return _focus_guard();
|
||||||
|
}
|
||||||
|
|
||||||
|
return guard_weird;
|
||||||
|
}
|
||||||
|
|
||||||
void _signal_handler(int sig, siginfo_t *si, void *unused) {
|
void _signal_handler(int sig, siginfo_t *si, void *unused) {
|
||||||
switch (sig) {
|
switch (sig) {
|
||||||
case SIGSEGV:
|
case SIGSEGV:
|
||||||
guard_err = _focus_guard(si->si_addr);
|
guard_err = _slash_guard(si->si_addr);
|
||||||
break;
|
break;
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
guard_err = guard_erupt;
|
guard_err = guard_erupt;
|
||||||
@ -67,38 +83,32 @@ void _signal_handler(int sig, siginfo_t *si, void *unused) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
guard_err_t _register_handler() {
|
guard_error _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 = _signal_handler;
|
sa.sa_sigaction = _signal_handler;
|
||||||
sa.sa_mask = 0;
|
sa.sa_mask = 0;
|
||||||
|
|
||||||
if (sigaction(SIGSEGV, &sa, NULL)) {
|
if (sigaction(SIGSEGV, &sa, NULL) || sigaction(SIGINT, &sa, NULL)) {
|
||||||
err = guard_weird;
|
return guard_weird;
|
||||||
}
|
}
|
||||||
|
|
||||||
return guard_err;
|
return guard_sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
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_t err;
|
|
||||||
stack_p = *stack;
|
stack_p = *stack;
|
||||||
alloc_p = *alloc;
|
alloc_p = *alloc;
|
||||||
|
|
||||||
if (_register_handler() != guard_sound) {
|
if (_register_handler() != guard_sound) {
|
||||||
err = guard_weird;
|
guard_err = guard_weird;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (guard_p == NULL) {
|
if (guard_p == NULL && (guard_err = _focus_guard()) != guard_sound) {
|
||||||
guard_p = stack_p + ((alloc_p - stack_p) / 2);
|
|
||||||
if (mprotect(guard_p, GD_PAGESZ, PROT_NONE) == -1) {
|
|
||||||
err = guard_armor;
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
*ret = f(arg);
|
*ret = f(arg);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user