You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2019/03/02 17:29:18 UTC

[mynewt-core] branch master updated: kernel/os: Fix mem corruption on 0-entry mempool

This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git


The following commit(s) were added to refs/heads/master by this push:
     new dab991c  kernel/os: Fix mem corruption on 0-entry mempool
dab991c is described below

commit dab991cbbf70044d7a9cf2324b56b38730a65884
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Wed Feb 20 15:40:07 2019 -0800

    kernel/os: Fix mem corruption on 0-entry mempool
    
    This fixes a memory corruption bug.  When a mempool was initialized with
    0 elements, its 0-length buffer would still be written to.  The bad
    write occurred when setting the last element's `next` pointer to NULL
    here:
    
        /* Last one in the list should be NULL */
        SLIST_NEXT(block_ptr, mb_next) = NULL;
    
    The fix is to only perform this final write if there is at least one
    element in the pool.
---
 kernel/os/src/os_mempool.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/kernel/os/src/os_mempool.c b/kernel/os/src/os_mempool.c
index 53002ea..72bf804 100644
--- a/kernel/os/src/os_mempool.c
+++ b/kernel/os/src/os_mempool.c
@@ -121,6 +121,7 @@ os_mempool_init_internal(struct os_mempool *mp, uint16_t blocks,
                          uint8_t flags)
 {
     int true_block_size;
+    int i;
     uint8_t *block_addr;
     struct os_memblock *block_ptr;
 
@@ -150,26 +151,27 @@ os_mempool_init_internal(struct os_mempool *mp, uint16_t blocks,
     mp->mp_num_blocks = blocks;
     mp->mp_membuf_addr = (uint32_t)membuf;
     mp->name = name;
-    os_mempool_poison(mp, membuf);
-    os_mempool_guard(mp, membuf);
     SLIST_FIRST(mp) = membuf;
 
-    true_block_size = OS_MEMPOOL_TRUE_BLOCK_SIZE(mp);
+    if (blocks > 0) {
+        os_mempool_poison(mp, membuf);
+        os_mempool_guard(mp, membuf);
+        true_block_size = OS_MEMPOOL_TRUE_BLOCK_SIZE(mp);
 
-    /* Chain the memory blocks to the free list */
-    block_addr = (uint8_t *)membuf;
-    block_ptr = (struct os_memblock *)block_addr;
-    while (blocks > 1) {
-        block_addr += true_block_size;
-        os_mempool_poison(mp, block_addr);
-        os_mempool_guard(mp, block_addr);
-        SLIST_NEXT(block_ptr, mb_next) = (struct os_memblock *)block_addr;
+        /* Chain the memory blocks to the free list */
+        block_addr = (uint8_t *)membuf;
         block_ptr = (struct os_memblock *)block_addr;
-        --blocks;
-    }
+        for (i = 1; i < blocks; i++) {
+            block_addr += true_block_size;
+            os_mempool_poison(mp, block_addr);
+            os_mempool_guard(mp, block_addr);
+            SLIST_NEXT(block_ptr, mb_next) = (struct os_memblock *)block_addr;
+            block_ptr = (struct os_memblock *)block_addr;
+        }
 
-    /* Last one in the list should be NULL */
-    SLIST_NEXT(block_ptr, mb_next) = NULL;
+        /* Last one in the list should be NULL */
+        SLIST_NEXT(block_ptr, mb_next) = NULL;
+    }
 
     STAILQ_INSERT_TAIL(&g_os_mempool_list, mp, mp_list);