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);