Skip to content

Commit

Permalink
Improve GglArena safety checks
Browse files Browse the repository at this point in the history
  • Loading branch information
archigup committed Oct 31, 2024
1 parent 9677145 commit b94ba6f
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
4 changes: 3 additions & 1 deletion ggl-lib/include/ggl/arena.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ static inline GglArena ggl_arena_init(GglBuffer buf) {
void *ggl_arena_alloc(GglArena *arena, size_t size, size_t alignment);

/// Resize ptr's allocation (must be the last allocated ptr).
GglError ggl_arena_resize_last(GglArena *arena, const void *ptr, size_t size);
GglError ggl_arena_resize_last(
GglArena *arena, const void *ptr, size_t old_size, size_t size
);

/// Returns true if arena's mem contains ptr.
bool ggl_arena_owns(const GglArena *arena, const void *ptr);
Expand Down
36 changes: 32 additions & 4 deletions ggl-lib/src/arena.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void *ggl_arena_alloc(GglArena *arena, size_t size, size_t alignment) {
assert((alignment > 0) && ((alignment & (alignment - 1)) == 0));
assert(alignment < UINT32_MAX);
// Allocation can't exceed ptrdiff_t, and this is likely a bug.
assert(size <= (UINT32_MAX >> 1));
assert(size <= PTRDIFF_MAX);

uint32_t align = (uint32_t) alignment;
uint32_t pad = (align - (arena->index & (align - 1))) & (align - 1);
Expand Down Expand Up @@ -46,13 +46,41 @@ void *ggl_arena_alloc(GglArena *arena, size_t size, size_t alignment) {
return &arena->MEM[idx];
}

GglError ggl_arena_resize_last(GglArena *arena, const void *ptr, size_t size) {
assert(ggl_arena_owns(arena, ptr));
GglError ggl_arena_resize_last(
GglArena *arena, const void *ptr, size_t old_size, size_t size
) {
assert(old_size < UINT32_MAX);
assert(old_size <= PTRDIFF_MAX);
assert(size <= PTRDIFF_MAX);

if (!ggl_arena_owns(arena, ptr)) {
GGL_LOGE("[%p] Resize ptr %p not owned.", arena, ptr);
assert(false);
return GGL_ERR_INVALID;
}

uint32_t idx = (uint32_t) ((uintptr_t) ptr - (uintptr_t) arena->MEM);

if (idx > arena->index) {
GGL_LOGE("[%p] Resize ptr %p out of allocated range.", arena, ptr);
assert(false);
return GGL_ERR_INVALID;
}

if (arena->index - idx != old_size) {
GGL_LOGE(
"[%p] Resize ptr %p + size %zu does not match allocation index",
arena,
ptr,
old_size
);
return GGL_ERR_INVALID;
}

if (size > arena->CAPACITY - idx) {
GGL_LOGD("[%p] Insufficient memory for resize to %zu.", arena, size);
GGL_LOGD(
"[%p] Insufficient memory to resize %p to %zu.", arena, ptr, size
);
return GGL_ERR_NOMEM;
}

Expand Down

0 comments on commit b94ba6f

Please sign in to comment.