Skip to content

Commit be15342

Browse files
malloc overflow checks + rename '__' to '_' to avoid potentially reserved compiler names
1 parent af53424 commit be15342

File tree

1 file changed

+38
-35
lines changed

1 file changed

+38
-35
lines changed

kernel/src/drivers/allocator.c

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#include "allocator.h"
22

3-
static uint8_t* __heap_start = NULL;
4-
static size_t __heap_size;
3+
static uint8_t* _heap_start = NULL;
4+
static size_t _heap_size;
55

6-
static MemoryHeader_t* __heap_first = NULL;
7-
static MemoryHeader_t* __heap_last = NULL;
6+
static MemoryHeader_t* _heap_first = NULL;
7+
static MemoryHeader_t* _heap_last = NULL;
88

99
/**
1010
* Get the memory block header corresponding to a data pointer.
@@ -30,7 +30,7 @@ static void __defragment_address(MemoryHeader_t* header) {
3030
if (next->next == NULL) {
3131
// this has to be the end, otherwise something has gone very wrong...
3232
header->next = NULL;
33-
__heap_last = header;
33+
_heap_last = header;
3434
// dropping extra headers is intentional, it enables avoiding a search
3535
// in malloc and just appending to the end of the heap
3636
} else {
@@ -57,29 +57,29 @@ void alloc_init(uint8_t* heap_start, size_t size) {
5757
// just to filter out basic errors
5858
if (heap_start == NULL || size < sizeof(MemoryHeader_t) * 4) return;
5959

60-
__heap_start = heap_start;
61-
__heap_size = size;
60+
_heap_start = heap_start;
61+
_heap_size = size;
6262

63-
__heap_first = (MemoryHeader_t*)__heap_start;
64-
__heap_first->size = 0;
65-
__heap_first->in_use = true;
66-
__heap_first->next = NULL;
67-
__heap_last = __heap_first;
63+
_heap_first = (MemoryHeader_t*)_heap_start;
64+
_heap_first->size = 0;
65+
_heap_first->in_use = true;
66+
_heap_first->next = NULL;
67+
_heap_last = _heap_first;
6868
}
6969

7070
/**
7171
* Release all allocated heap blocks and reset the allocator state.
7272
*
7373
* Frees every MemoryHeader_t in the managed heap and sets internal allocator
74-
* globals (__heap_start, __heap_size, __heap_first, __heap_last) to indicate
74+
* globals (_heap_start, _heap_size, _heap_first, _heap_last) to indicate
7575
* the heap is uninitialized. After this call, allocations will fail until
7676
* alloc_init is called again.
7777
*/
7878
void alloc_free() {
79-
__heap_start = NULL;
80-
__heap_size = 0;
81-
__heap_first = NULL;
82-
__heap_last = NULL;
79+
_heap_start = NULL;
80+
_heap_size = 0;
81+
_heap_first = NULL;
82+
_heap_last = NULL;
8383
}
8484

8585
/**
@@ -92,31 +92,34 @@ void alloc_free() {
9292
* uninitialized or no suitable block is available.
9393
*/
9494
void* malloc(size_t bytes) {
95-
if (__heap_start == NULL || bytes == 0) return NULL;
95+
if (_heap_start == NULL || bytes == 0) return NULL;
9696

9797
// check if we have room to allocate memory
9898
// at the end of the currently used heap
99-
uintptr_t end_of_new_block = (uintptr_t)__heap_last
100-
+ sizeof(MemoryHeader_t) + (uintptr_t)__heap_last->size
101-
+ sizeof(MemoryHeader_t) + (uintptr_t)bytes;
102-
if (end_of_new_block < (uintptr_t)__heap_start + (uintptr_t)__heap_size) {
103-
__heap_last->next = (MemoryHeader_t*)(
104-
(uint8_t*)__heap_last
105-
+ __heap_last->size
99+
uintptr_t heap_end =
100+
(uintptr_t)_heap_last + sizeof(MemoryHeader_t) + _heap_last->size;
101+
size_t new_block_size = sizeof(MemoryHeader_t) + bytes;
102+
if (new_block_size > SIZE_MAX - heap_end) return NULL;
103+
104+
if (heap_end + new_block_size
105+
< (uintptr_t)_heap_start + (uintptr_t)_heap_size) {
106+
_heap_last->next = (MemoryHeader_t*)(
107+
(uint8_t*)_heap_last
108+
+ _heap_last->size
106109
+ sizeof(MemoryHeader_t)
107110
);
108111

109-
__heap_last = __heap_last->next;
112+
_heap_last = _heap_last->next;
110113

111-
__heap_last->size = bytes;
112-
__heap_last->in_use = true;
113-
__heap_last->next = NULL;
114+
_heap_last->size = bytes;
115+
_heap_last->in_use = true;
116+
_heap_last->next = NULL;
114117

115-
return (void*)(__heap_last + 1);
118+
return (void*)(_heap_last + 1);
116119
}
117120

118121
// search for an unused block
119-
MemoryHeader_t* search = __heap_first;
122+
MemoryHeader_t* search = _heap_first;
120123
while (search != NULL &&
121124
(search->in_use ||
122125
bytes > search->size)) {
@@ -157,7 +160,7 @@ void* malloc(size_t bytes) {
157160
fragment->size = remaining_space - sizeof(MemoryHeader_t);
158161
fragment->in_use = false;
159162
fragment->next = search->next;
160-
if (fragment->next == NULL) __heap_last = fragment;
163+
if (fragment->next == NULL) _heap_last = fragment;
161164

162165
search->size = bytes;
163166
search->next = fragment;
@@ -243,14 +246,14 @@ void free(void* ptr) {
243246
* Coalesces adjacent free blocks in the allocator's heap to reduce
244247
* fragmentation.
245248
*
246-
* Traverses the allocator's header list starting at __heap_first and merges
249+
* Traverses the allocator's header list starting at _heap_first and merges
247250
* consecutive blocks that are not in use by increasing the earlier block's
248251
* size and updating next pointers; modifies the allocator's heap metadata.
249252
*/
250253
static void __defragment_all() {
251-
if (__heap_first == NULL) return;
254+
if (_heap_first == NULL) return;
252255

253-
MemoryHeader_t* current = __heap_first;
256+
MemoryHeader_t* current = _heap_first;
254257
while (current->next != NULL) {
255258
__defragment_address(current);
256259
current = current->next;

0 commit comments

Comments
 (0)