Skip to content

Commit 65fd0e6

Browse files
committed
implemented kernel heap canaries
1 parent 93828fb commit 65fd0e6

File tree

3 files changed

+68
-9
lines changed

3 files changed

+68
-9
lines changed

config/kernel.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
{
4040
"name": "EARLY_SERIAL_DEBUG",
4141
"value": true
42+
},
43+
{
44+
"name": "HEAP_CANARY",
45+
"value": true
4246
}
4347
]
4448
}

mckrnl/core/include/config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define ALLOW_PANIC_CONTINUE
1111
#define STACK_TRACE
1212
#define EARLY_SERIAL_DEBUG
13+
#define HEAP_CANARY
1314
// End Debug
1415

1516
// Network

mckrnl/core/memory/heap.c

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@
77
#include <stdio.h>
88
#include <utils/trace.h>
99

10+
#include <config.h>
11+
12+
#ifdef HEAP_CANARY
13+
#define HEAP_CANARY_VALUE 0xDEADBEEF
14+
typedef unsigned int heap_canary_t;
15+
#endif
16+
17+
1018
void* heap_start;
1119
void* heap_end;
1220
heap_segment_header_t* last_hdr;
@@ -91,7 +99,7 @@ void print_allocations(const char* msg) {
9199

92100
debugf("--- Heap allocations: %s ---", msg);
93101
while(true) {
94-
debugf("0x%x (%d bytes) free: %s", ((uint32_t) current_seg + sizeof(heap_segment_header_t)), current_seg->length, current_seg->free ? "true" : "false");
102+
debugf("0x%x (%d bytes) free: %s", current_seg, current_seg->length, current_seg->free ? "true" : "false");
95103

96104
if (current_seg->next == NULL) {
97105
break;
@@ -102,6 +110,28 @@ void print_allocations(const char* msg) {
102110
debugf("--- End of heap allocations ---");
103111
}
104112

113+
#ifdef HEAP_CANARY
114+
void check_heap_canaries() {
115+
heap_segment_header_t* current_seg = (heap_segment_header_t*) heap_start;
116+
117+
while(true) {
118+
if (!current_seg->free) {
119+
void* ptr = (void*) ((uintptr_t) current_seg + sizeof(heap_segment_header_t));
120+
heap_canary_t* canary_ptr = (heap_canary_t*) ((uintptr_t) ptr + current_seg->length - sizeof(heap_canary_t));
121+
if (*canary_ptr != HEAP_CANARY_VALUE) {
122+
abortf(false, "heap canary corrupted at segment 0x%x. Expected 0x%x but was 0x%x. Canary location: 0x%x", current_seg, HEAP_CANARY_VALUE, *canary_ptr, canary_ptr);
123+
}
124+
}
125+
126+
if (current_seg->next == NULL) {
127+
break;
128+
}
129+
130+
current_seg = current_seg->next;
131+
}
132+
}
133+
#endif
134+
105135
#if 0
106136
void expand_heap(size_t length) {
107137
print_allocations("Before expanding heap");
@@ -132,27 +162,42 @@ void expand_heap(size_t length) {
132162
}
133163
#endif
134164

165+
void* prepare_segment(heap_segment_header_t* segment) {
166+
segment->free = false;
167+
void* ptr = (void*) ((uintptr_t) segment + sizeof(heap_segment_header_t));
168+
169+
#ifdef HEAP_CANARY
170+
heap_canary_t* canary_ptr = (heap_canary_t*) ((uintptr_t) ptr + segment->length - sizeof(heap_canary_t));
171+
*canary_ptr = HEAP_CANARY_VALUE;
172+
#endif
173+
174+
return ptr;
175+
}
176+
135177
void* kmalloc(size_t size) {
178+
if (size == 0) {
179+
return NULL;
180+
}
181+
182+
#ifdef HEAP_CANARY
183+
check_heap_canaries();
184+
size += sizeof(heap_canary_t);
185+
#endif
186+
136187
if (size % 0x10 > 0) { // it is not a multiple of 0x10
137188
size -= (size % 0x10);
138189
size += 0x10;
139190
}
140191

141-
if (size == 0) {
142-
return NULL;
143-
}
144-
145192
heap_segment_header_t* current_seg = (heap_segment_header_t*) heap_start;
146193
while(true) {
147194
if (current_seg->free) {
148195
if (current_seg->length > size) {
149196
hsh_split(current_seg, size);
150-
current_seg->free = false;
151-
return (void*) ((uint32_t) current_seg + sizeof(heap_segment_header_t));
197+
return prepare_segment(current_seg);
152198
}
153199
if (current_seg->length == size) {
154-
current_seg->free = false;
155-
return (void*) ((uint32_t) current_seg + sizeof(heap_segment_header_t));
200+
return prepare_segment(current_seg);
156201
}
157202
}
158203

@@ -180,7 +225,11 @@ void* krealloc(void* ptr, size_t size) {
180225
return NULL;
181226
} else if (!ptr) {
182227
return kmalloc(size);
228+
#ifdef HEAP_CANARY
229+
} else if (size + sizeof(heap_canary_t) <= segment->length) {
230+
#else
183231
} else if (size <= segment->length) {
232+
#endif
184233
return ptr;
185234
} else {
186235
void* new_ptr = kmalloc(size);
@@ -196,6 +245,11 @@ void kfree(void* address) {
196245
if (address == NULL) {
197246
return;
198247
}
248+
249+
#ifdef HEAP_CANARY
250+
check_heap_canaries();
251+
#endif
252+
199253
heap_segment_header_t* segment = (heap_segment_header_t*) address - 1;
200254
segment->free = true;
201255
hsh_combine_forward(segment);

0 commit comments

Comments
 (0)