Module: xenomai-3
Branch: master
Commit: 3746052918643aad50cedbec47df54f03a1f0b92
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=3746052918643aad50cedbec47df54f03a1f0b92

Author: Philippe Gerum <r...@xenomai.org>
Date:   Thu Sep 22 11:27:58 2016 +0200

copperplate/heapobj: pshared: fix corruption of sub-page block list

Block allocation requests between HOBJ_PAGE_SIZE and HOBJ_PAGE_SIZE *
2 are satisfied by returning free raw pages directly, in which case
there is no free sub-page block list attached to the corresponding
log2 slot. Make sure we don't create a spurious one inadvertently.

This fixes a crash on such an allocation/release pattern:

    int *p = xnmalloc(1400);
    p[0] = -1;
    xnfree(p);
    xnmalloc(512);
    xnmalloc(512);

Reported-by: Jan Kiszka <jan.kis...@siemens.com>

---

 lib/copperplate/heapobj-pshared.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/lib/copperplate/heapobj-pshared.c 
b/lib/copperplate/heapobj-pshared.c
index f4c6f37..e02cfd3 100644
--- a/lib/copperplate/heapobj-pshared.c
+++ b/lib/copperplate/heapobj-pshared.c
@@ -437,10 +437,12 @@ static void *alloc_block(struct shared_heap *heap, size_t 
size)
                        block = get_free_range(heap, bsize, log2size);
                        if (block == NULL)
                                goto done;
-                       if (bsize <= HOBJ_PAGE_SIZE)
+                       if (bsize < HOBJ_PAGE_SIZE) {
                                heap->buckets[ilog].fcount += (HOBJ_PAGE_SIZE 
>> log2size) - 1;
+                               heap->buckets[ilog].freelist = *((memoff_t 
*)block);
+                       }
                } else {
-                       if (bsize <= HOBJ_PAGE_SIZE)
+                       if (bsize < HOBJ_PAGE_SIZE)
                                --heap->buckets[ilog].fcount;
 
                        /* Search for the source extent of block. */
@@ -453,9 +455,9 @@ static void *alloc_block(struct shared_heap *heap, size_t 
size)
                found:
                        pgnum = (__shoff(base, block) - extent->membase) >> 
HOBJ_PAGE_SHIFT;
                        ++extent->pagemap[pgnum].bcount;
+                       heap->buckets[ilog].freelist = *((memoff_t *)block);
                }
 
-               heap->buckets[ilog].freelist = *((memoff_t *)block);
                heap->ubytes += bsize;
        } else {
                if (size > heap->maxcont)


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai-git

Reply via email to