From 34faa01b8e9e2ec6af2fe6ecf336666066c21452 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 9 Jan 2023 18:25:35 +0000 Subject: [PATCH] Fixed bounded memblock iteration including negative-sized regions --- sandbox/memblock/memblock.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/sandbox/memblock/memblock.c b/sandbox/memblock/memblock.c index fd94698..5065ec5 100644 --- a/sandbox/memblock/memblock.c +++ b/sandbox/memblock/memblock.c @@ -271,6 +271,10 @@ void __next_memory_region(memblock_iter_t *it, memblock_type_t *type_a, memblock for (; idx_a < type_a->count; idx_a++) { memblock_region_t *m = &type_a->regions[idx_a]; + + uintptr_t m_start = m->base; + uintptr_t m_end = m->limit; + if (!type_b) { it->it_base = m->base; it->it_limit = m->limit; @@ -280,9 +284,6 @@ void __next_memory_region(memblock_iter_t *it, memblock_type_t *type_a, memblock return; } - uintptr_t m_start = m->base; - uintptr_t m_end = m->limit; - if (m_end < start) { /* we haven't reached the requested memory range yet */ continue; @@ -300,9 +301,24 @@ void __next_memory_region(memblock_iter_t *it, memblock_type_t *type_a, memblock * if we have gone past the last reserved region, these variables delimit the range between the end * of the last reserved region and the end of memory. */ uintptr_t r_start = idx_b > 0 ? r[-1].limit + 1 : 0; - uintptr_t r_end = idx_b < type_b->count ? r->base : ADDR_MAX; + uintptr_t r_end; - if (r_start == r_end) { + if (idx_b < type_b->count) { + r_end = r->base; + + /* we decrement r_end to get the address of the last byte of the free region. + if r_end is already zero, there is a reserved region starting at address 0x0. + as long as r_end == r_start == 0x00000, we will skip this region. */ + if (r_end) { + r_end--; + } + } else { + /* this maximum value will be clamped to the bounds of memblock.memory + before being returned to the caller */ + r_end = ADDR_MAX; + } + + if (r_start >= r_end) { /* this free region has a length of zero, move to the next one */ continue; } @@ -329,6 +345,11 @@ void __next_memory_region(memblock_iter_t *it, memblock_type_t *type_a, memblock it->it_base = MAX(it->it_base, start); it->it_limit = MIN(it->it_limit, end); + if (it->it_limit <= it->it_base) { + /* this region is not part of the specified bounds, skip it. */ + continue; + } + it->it_status = MEMBLOCK_MEMORY; /* whichever region is smaller, increment the pointer for that type, so we can