From b014f1cd12262afee9933d7c07d61242edc28a95 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 16 Mar 2026 14:31:52 +0100 Subject: kernel/heap: fix infinite allocation loop --- kernel/src/memory/block_list_allocator.cpp | 64 +++++++++++++++--------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/kernel/src/memory/block_list_allocator.cpp b/kernel/src/memory/block_list_allocator.cpp index 1bd17ff..5d870d8 100644 --- a/kernel/src/memory/block_list_allocator.cpp +++ b/kernel/src/memory/block_list_allocator.cpp @@ -42,51 +42,49 @@ namespace kernel::memory auto current = m_block_list; while (current != nullptr) { - if (!current->free) + if (current->free) { - current = current->next; - continue; - } + auto const raw_block = reinterpret_cast(current); + auto const unaligned_payload = raw_block + allocated_metadata_size; + auto const aligned_payload = align_up(unaligned_payload, alignment); + auto const required_padding = static_cast(aligned_payload - unaligned_payload); + auto const total_required_size = required_padding + allocated_metadata_size + size; - auto const raw_block = reinterpret_cast(current); - auto const unaligned_payload = raw_block + allocated_metadata_size; - auto const aligned_payload = align_up(unaligned_payload, alignment); - auto const required_padding = static_cast(aligned_payload - unaligned_payload); - auto const total_required_size = required_padding + allocated_metadata_size + size; + if (current->usable_size >= total_required_size) + { + auto const payload_header = aligned_payload - sizeof(block_header *) - sizeof(block_header); + auto const front_padding = static_cast(payload_header - raw_block); - if (current->usable_size >= total_required_size) - { - auto const payload_header = aligned_payload - sizeof(block_header *) - sizeof(block_header); - auto const front_padding = static_cast(payload_header - raw_block); + auto payload_block = current; - auto payload_block = current; + if (front_padding >= allocated_metadata_size + minimum_allocation_size) + { + payload_block = reinterpret_cast(payload_header); + std::construct_at(payload_block, current->usable_size - front_padding, true, current->next); - if (front_padding >= allocated_metadata_size + minimum_allocation_size) - { - payload_block = reinterpret_cast(payload_header); - std::construct_at(payload_block, current->usable_size - front_padding, true, current->next); + if (payload_block->next) + { + payload_block->next->prev = payload_block; + } - if (payload_block->next) - { - payload_block->next->prev = payload_block; + current->usable_size = front_padding - allocated_metadata_size; + current->next = payload_block; + payload_block->prev = current; } - current->usable_size = front_padding - allocated_metadata_size; - current->next = payload_block; - payload_block->prev = current; - } - - auto const payload_size = - aligned_payload - reinterpret_cast(payload_block) - allocated_metadata_size + size; - split(payload_block, payload_size, 0uz); + auto const payload_size = + aligned_payload - reinterpret_cast(payload_block) - allocated_metadata_size + size; + split(payload_block, payload_size, 0uz); - payload_block->free = false; + payload_block->free = false; - auto back_pointer = reinterpret_cast(aligned_payload - sizeof(block_header *)); - *back_pointer = payload_block; + auto back_pointer = reinterpret_cast(aligned_payload - sizeof(block_header *)); + *back_pointer = payload_block; - return reinterpret_cast(aligned_payload); + return reinterpret_cast(aligned_payload); + } } + current = current->next; } auto const search_size = size + static_cast(alignment); -- cgit v1.2.3