From ace11bbefde384af7e0bf7c2f7b9fc6a1c9c88ca Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Sun, 26 May 2019 21:12:05 -0400 Subject: [PATCH] mempool: make sure max block size isn't smaller than minimum allowed If maxsize is smaller than _MPOOL_MINBLK, then Z_MPOOL_LVLS() will be 0. That means the loop in z_sys_mem_pool_base_init() that initializes the block free list for the nonexistent level 0 will corrupt whatever memory at the location the zero-sized struct sys_mem_pool_lvl array was located. And the corruption happens to be done with a perfectly legit memory pool block address which makes for really nasty bugs to solve. This is more likely on 64-bit systems due to _MPOOL_MINBLK being twice the size of 32-bit systems. Let's prevent that with a build-time assertion on maxsize when defining a memory pool, and adjust the affected test accordingly. Signed-off-by: Nicolas Pitre --- include/kernel.h | 1 + include/sys/mempool.h | 1 + tests/kernel/queue/src/test_queue_contexts.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/kernel.h b/include/kernel.h index 2a38e284905..2d912497e4f 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -4159,6 +4159,7 @@ struct k_mem_pool { * @req K-MPOOL-001 */ #define K_MEM_POOL_DEFINE(name, minsz, maxsz, nmax, align) \ + BUILD_ASSERT(WB_UP(maxsz) >= _MPOOL_MINBLK); \ char __aligned(WB_UP(align)) _mpool_buf_##name[WB_UP(maxsz) * nmax \ + _MPOOL_BITS_SIZE(maxsz, minsz, nmax)]; \ struct sys_mem_pool_lvl _mpool_lvls_##name[Z_MPOOL_LVLS(maxsz, minsz)]; \ diff --git a/include/sys/mempool.h b/include/sys/mempool.h index cf2b29d111d..a367f6e8c4b 100644 --- a/include/sys/mempool.h +++ b/include/sys/mempool.h @@ -47,6 +47,7 @@ struct sys_mem_pool_block { * @param section Destination binary section for pool data */ #define SYS_MEM_POOL_DEFINE(name, ignored, minsz, maxsz, nmax, align, section) \ + BUILD_ASSERT(WB_UP(maxsz) >= _MPOOL_MINBLK); \ char __aligned(WB_UP(align)) Z_GENERIC_SECTION(section) \ _mpool_buf_##name[WB_UP(maxsz) * nmax \ + _MPOOL_BITS_SIZE(maxsz, minsz, nmax)]; \ diff --git a/tests/kernel/queue/src/test_queue_contexts.c b/tests/kernel/queue/src/test_queue_contexts.c index 22ff000d646..d32935773e7 100644 --- a/tests/kernel/queue/src/test_queue_contexts.c +++ b/tests/kernel/queue/src/test_queue_contexts.c @@ -11,7 +11,7 @@ /**TESTPOINT: init via K_QUEUE_DEFINE*/ K_QUEUE_DEFINE(kqueue); -K_MEM_POOL_DEFINE(mem_pool_fail, 4, 8, 1, 4); +K_MEM_POOL_DEFINE(mem_pool_fail, 4, _MPOOL_MINBLK, 1, 4); K_MEM_POOL_DEFINE(mem_pool_pass, 4, 64, 4, 4); struct k_queue queue;