guard: partially address @ashelkovnykov's comments

This commit is contained in:
Matthew LeVan 2024-02-20 02:53:14 -05:00
parent b1e3b788b1
commit d13fe50c72
3 changed files with 18 additions and 20 deletions

View File

@ -34,7 +34,7 @@ static GD_state gd = {
.prev_sigbus_sa = { .sa_sigaction = NULL, .sa_flags = 0 },
};
static guard_result
static guard_err
_protect_page(void *address, int prot)
{
if (mprotect(address, GD_PAGE_SIZE, prot)) {
@ -43,18 +43,18 @@ _protect_page(void *address, int prot)
return guard_mprotect | errno;
}
return guard_success;
return 0;
}
// Center the guard page.
static guard_result
static guard_err
_focus_guard()
{
uintptr_t stack_p = *gd.stack_pp;
uintptr_t alloc_p = *gd.alloc_pp;
uintptr_t old_guard_p = gd.guard_p;
uintptr_t new_guard_p;
guard_result err = guard_success;
guard_err err = 0;
if (stack_p == 0 || alloc_p == 0) {
fprintf(stderr, "guard: focus: stack or alloc pointer is null\r\n");
@ -86,14 +86,14 @@ _focus_guard()
}
}
return guard_success;
return 0;
}
static void
_signal_handler(int sig, siginfo_t *si, void *unused)
{
uintptr_t sig_addr;
guard_result err = guard_success;
guard_err err = 0;
assert(gd.guard_p);
@ -138,7 +138,7 @@ _signal_handler(int sig, siginfo_t *si, void *unused)
}
// Registers the same handler function for SIGSEGV and SIGBUS.
static guard_result
static guard_err
_register_handlers()
{
struct sigaction sa;
@ -157,10 +157,10 @@ _register_handlers()
return guard_sigaction | errno;
}
return guard_success;
return 0;
}
guard_result
guard_err
guard(
void *(*f)(void *),
void *closure,
@ -169,8 +169,8 @@ guard(
void **ret
) {
GD_buflistnode *new_buffer;
guard_result err = guard_success;
guard_result td_err = guard_success;
guard_err err = 0;
guard_err td_err = 0;
if (gd.guard_p == 0) {
assert(gd.buffer_list == NULL);

View File

@ -10,7 +10,7 @@
typedef struct GD_buflistnode GD_buflistnode;
struct GD_buflistnode {
jmp_buf buffer;
struct GD_buflistnode *next;
GD_buflistnode *next;
};
/**
@ -19,21 +19,20 @@ struct GD_buflistnode {
* The flags are bitwise added to the errno of their respective errors.
*/
typedef enum {
guard_success = 0, // successful return
guard_null = 1, // null stack or alloc pointer
guard_signal = 2, // invalid signal
guard_oom = 3, // out of memory
guard_malloc = 0x10000000, // malloc error flag
guard_mprotect = 0x20000000, // mprotect error flag
guard_sigaction = 0x40000000, // sigaction error flag
} guard_result;
} guard_err;
/**
* @brief Executes the given callback function `f` within the memory arena
* between the stack and allocation pointers pointed to by `s_pp` and `a_pp`,
* with guard page protection. If `f`'s execution succeeds, its result is
* written to the return pointer `*ret`. If `f`'s execution triggers an
* out of memory error or any other `guard_result`, the `guard_result` is
* out of memory error or any other `guard_err`, the `guard_err` is
* returned and `*ret` is left empty. In either case, cleanup is performed
* before returning.
*
@ -49,14 +48,14 @@ typedef enum {
* - The caller is responsible for managing any external state the callback
* function may mutate.
* - The callback function may be interrupted in the case of memory exhaustion
* or other `guard_result` error (failure to `mprotect`, `malloc`, etc.).
* or other `guard_err` error (failure to `mprotect`, `malloc`, etc.).
* - `SIGSEGV` signals are expected to be raised only on guard page accesses.
*
* Invariants:
* - A single guard page is installed and maintained in the approximate center
* until `crate::guard::call_with_guard` returns.
* - A return value is only written to `*ret` on successful callback execution.
* - A `guard_result` is returned, excepting panics or negative assertions.
* - A `guard_err` is returned, excepting panics or negative assertions.
*
* Enhancements:
* - Use only a single, static jump buffer variable instead of a linked list.
@ -70,9 +69,9 @@ typedef enum {
* @param a_pp A pointer to the allocation pointer location.
* @param ret A pointer to a location where the callback's result can be stored.
*
* @return A `guard_result` return code.
* @return A `guard_err` error code.
*/
guard_result
guard_err
guard(
void *(*f)(void *),
void *closure,

View File

@ -4,7 +4,6 @@
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
pub const GUARD_SUCCESS: u32 = guard_result_guard_success;
pub const GUARD_NULL: u32 = guard_result_guard_null;
pub const GUARD_SIGNAL: u32 = guard_result_guard_signal;
pub const GUARD_OOM: u32 = guard_result_guard_oom;