@@ -76,7 +76,7 @@ static void *kmalloc_internal(uint32_t size, int retry_count) {
7676 if (size == 0 || free_list == NULL ) {
7777 return NULL ;
7878 }
79-
79+
8080 /* Prevent infinite recursion */
8181 if (retry_count > 3 ) {
8282 printk ("mem: kmalloc retry limit exceeded\n" );
@@ -88,8 +88,11 @@ static void *kmalloc_internal(uint32_t size, int retry_count) {
8888
8989 uint32_t wanted = align_up (size );
9090
91- // ブロック全体の必要サイズ
92- uint32_t total_size = wanted + sizeof (block_header_t );
91+ /* Add space for canary at the end, then align the total */
92+ uint32_t wanted_with_canary = align_up (wanted + sizeof (uint32_t ));
93+
94+ // ブロック全体の必要サイズ (header + user data + canary, aligned)
95+ uint32_t total_size = wanted_with_canary + sizeof (block_header_t );
9396
9497 block_header_t * prev = NULL ;
9598 block_header_t * cur = free_list ;
@@ -125,7 +128,7 @@ static void *kmalloc_internal(uint32_t size, int retry_count) {
125128 cur = cur -> next ;
126129 continue ;
127130 }
128-
131+
129132 if (cur -> size >= total_size ) {
130133 if (cur -> size >=
131134 total_size + sizeof (block_header_t ) + ALIGN ) {
@@ -158,11 +161,10 @@ static void *kmalloc_internal(uint32_t size, int retry_count) {
158161 void * user_ptr = (void * )((uintptr_t )cur +
159162 sizeof (block_header_t ));
160163
161- /* Compute remaining free totals and largest contiguous block
162- * while still holding the heap_lock to avoid races. We avoid
163- * calling heap_free_bytes()/heap_largest_free_block() here
164- * because they would try to take the same lock.
165- */
164+ /* Calculate actual user bytes allocated (might be larger than wanted) */
165+ uint32_t actual_user_bytes =
166+ cur -> size - sizeof (block_header_t );
167+
166168 uint32_t total_free = 0 ;
167169 uint32_t largest = 0 ;
168170 block_header_t * it = free_list ;
@@ -185,18 +187,15 @@ static void *kmalloc_internal(uint32_t size, int retry_count) {
185187 user_ptr , total_free , largest );
186188 }
187189
188- if (wanted >= sizeof (uint32_t )) {
189- uint32_t * canary =
190- (uint32_t * )((uintptr_t )user_ptr +
191- wanted - sizeof (uint32_t ));
192- * canary = KMALLOC_CANARY ;
193- if (size >= 256 ) {
194- printk ("mem: set canary at %p (user_ptr=%p wanted=%u) value=0x%08x\n" ,
195- canary , user_ptr , wanted ,
196- * canary );
197- }
190+ /* Place canary at end of allocated space (before alignment padding) */
191+ uint32_t * canary =
192+ (uint32_t * )((uintptr_t )user_ptr + wanted_with_canary - sizeof (uint32_t ));
193+ * canary = KMALLOC_CANARY ;
194+ if (size >= 256 ) {
195+ printk ("mem: set canary at %p (user_ptr=%p wanted=%u wanted_with_canary=%u actual_allocated=%u) value=0x%08x\n" ,
196+ canary , user_ptr ,
197+ wanted , wanted_with_canary , actual_user_bytes , * canary );
198198 }
199-
200199 spin_unlock_irqrestore (& heap_lock , flags );
201200 return user_ptr ;
202201 }
@@ -207,7 +206,7 @@ static void *kmalloc_internal(uint32_t size, int retry_count) {
207206
208207 // 見つからなかった - ヒープを拡張してリトライ
209208 spin_unlock_irqrestore (& heap_lock , flags );
210-
209+
211210 uint32_t expand_size = total_size ;
212211 if (expand_size < 0x100000 ) /* 1MB minimum */
213212 expand_size = 0x100000 ;
@@ -252,30 +251,32 @@ void kfree(void *ptr) {
252251 }
253252
254253 // フリーリストに挿入(アドレス順に保つ)
255- if (hdr -> size > sizeof (block_header_t ) &&
256- hdr -> size - sizeof (block_header_t ) >= sizeof (uint32_t )) {
257- uint32_t user_bytes = hdr -> size - sizeof (block_header_t );
254+ /* Check canary: it's placed at user_area_end - 4 bytes */
255+ if (hdr -> size > sizeof (block_header_t ) + sizeof (uint32_t )) {
256+ uint32_t user_bytes_with_canary =
257+ hdr -> size - sizeof (block_header_t );
258258 uint32_t * canary =
259259 (uint32_t * )((uintptr_t )hdr + sizeof (block_header_t ) +
260- user_bytes - sizeof (uint32_t ));
260+ user_bytes_with_canary -
261+ sizeof (uint32_t ));
261262 if (* canary != KMALLOC_CANARY ) {
262263 uint32_t got = * canary ;
263264 uint32_t tag = hdr -> tag ;
264265 printk ("mem: kfree CANARY MISMATCH for ptr=%p hdr=%p hdr->size=%u id=%u expected=0x%08x got=0x%08x\n" ,
265266 ptr , hdr , hdr -> size , tag ,
266267 (unsigned )KMALLOC_CANARY , (unsigned )got );
267268
268- uint32_t user_bytes =
269- hdr -> size - sizeof (block_header_t );
270269 uint8_t * user_ptr =
271270 (uint8_t * )hdr + sizeof (block_header_t );
272271 uint8_t * ctx_start =
273- user_ptr +
274- (user_bytes > 16 ? user_bytes - 16 : 0 );
275- uint32_t ctx_len = (user_bytes > 16 ) ? 24 :
276- (user_bytes + 8 );
277- if (ctx_len > user_bytes + 8 )
278- ctx_len = user_bytes + 8 ;
272+ user_ptr + (user_bytes_with_canary > 16 ?
273+ user_bytes_with_canary - 16 :
274+ 0 );
275+ uint32_t ctx_len = (user_bytes_with_canary > 16 ) ?
276+ 24 :
277+ (user_bytes_with_canary + 8 );
278+ if (ctx_len > user_bytes_with_canary + 8 )
279+ ctx_len = user_bytes_with_canary + 8 ;
279280 if (ctx_len > 64 )
280281 ctx_len = 64 ;
281282 printk ("mem: dumping %u bytes around canary (hex): " ,
@@ -337,12 +338,12 @@ static int heap_expand(uint32_t additional_size) {
337338 * Instead, directly use the memory at heap_end_addr (identity-mapped).
338339 * Physical frame reservation can be done separately if needed.
339340 */
340-
341+
341342 uintptr_t new_block_addr = heap_end_addr ;
342-
343+
343344 printk ("mem: heap_expand creating block at 0x%08x size=%u (direct allocation, no frame alloc)\n" ,
344345 (uint32_t )new_block_addr , additional_size );
345-
346+
346347 uint32_t flags = 0 ;
347348 spin_lock_irqsave (& heap_lock , & flags );
348349
@@ -359,13 +360,13 @@ static int heap_expand(uint32_t additional_size) {
359360 } else {
360361 block_header_t * prev = NULL ;
361362 block_header_t * cur = free_list ;
362-
363+
363364 /* Find insertion point to maintain address order */
364365 while (cur && (uintptr_t )cur < (uintptr_t )new_block ) {
365366 prev = cur ;
366367 cur = cur -> next ;
367368 }
368-
369+
369370 if (prev == NULL ) {
370371 /* Insert at head */
371372 new_block -> next = free_list ;
@@ -376,20 +377,22 @@ static int heap_expand(uint32_t additional_size) {
376377 new_block -> next = prev -> next ;
377378 prev -> next = new_block ;
378379 printk ("mem: heap_expand inserted after 0x%p\n" , prev );
379-
380+
380381 /* Try to merge with previous block if adjacent */
381382 uintptr_t prev_end = (uintptr_t )prev + prev -> size ;
382383 if (prev_end == (uintptr_t )new_block ) {
383384 printk ("mem: heap_expand merging with previous block\n" );
384385 prev -> size += new_block -> size ;
385386 prev -> next = new_block -> next ;
386- new_block = prev ; /* For potential merge with next */
387+ new_block =
388+ prev ; /* For potential merge with next */
387389 }
388390 }
389-
391+
390392 /* Try to merge with next block if adjacent */
391393 if (new_block -> next ) {
392- uintptr_t new_end = (uintptr_t )new_block + new_block -> size ;
394+ uintptr_t new_end =
395+ (uintptr_t )new_block + new_block -> size ;
393396 if (new_end == (uintptr_t )new_block -> next ) {
394397 printk ("mem: heap_expand merging with next block\n" );
395398 block_header_t * next = new_block -> next ;
0 commit comments