DF-5691 / guardalloc.h
/* * DF-5691 rig-only page-guard allocator. * * Every allocation is page-aligned, ends directly against a PROT_NONE * guard page, and is munmap()ed on free. Any read/write past the end of * an allocation, or any access after free, SIGSEGVs deterministically. * (Guest base cc 8.3 has no usable ASAN runtime -> page guards instead.) * * Redirected onto proplib in the rig builds via prop_object_impl.h: * _PROP_MALLOC/_PROP_CALLOC/_PROP_REALLOC/_PROP_FREE and * _PROP_POOL_GET/_PROP_POOL_PUT (userland block only; see build.sh). */ #ifndef DF5691_GUARDALLOC_H #define DF5691_GUARDALLOC_H #include <stddef.h> #include <stdint.h> #include <string.h> #include <sys/mman.h> #include <unistd.h> static size_t ga_pagesz(void) { static size_t ps; if (ps == 0) ps = (size_t)sysconf(_SC_PAGESIZE); return (ps); } /* layout: [header page: size][data pages ...][PROT_NONE guard page] */ static void * ga_malloc(size_t size) { size_t ps = ga_pagesz(); size_t need = (size + ps - 1) & ~(ps - 1); unsigned char *m; if (size == 0) size = 1, need = ps; m = mmap(NULL, ps + need + ps, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); if (m == MAP_FAILED || m == NULL) return (NULL); if (mprotect(m + ps + need, ps, PROT_NONE) != 0) { munmap(m, ps + need + ps); return (NULL); } *(size_t *)(void *)m = size; return (m + ps); } static void * ga_calloc(size_t n, size_t size) { void *p = ga_malloc(n * size); if (p != NULL) memset(p, 0, n * size); return (p); } static void ga_free(void *p) { size_t ps = ga_pagesz(); unsigned char *m; size_t size, need; if (p == NULL) return; m = (unsigned char *)p - ps; size = *(size_t *)(void *)m; need = (size + ps - 1) & ~(ps - 1); munmap(m, ps + need + ps); } static void * ga_realloc(void *v, size_t size) { unsigned char *m; size_t old; void *n; if (v == NULL) return (ga_malloc(size)); m = (unsigned char *)v - ga_pagesz(); old = *(size_t *)(void *)m; n = ga_malloc(size); if (n == NULL) return (NULL); memcpy(n, v, old < size ? old : size); ga_free(v); return (n); } #endif /* DF5691_GUARDALLOC_H */ |