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+
1018void * heap_start ;
1119void * heap_end ;
1220heap_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
106136void 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+
135177void * 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