Skip to content

Commit

Permalink
mempool: make sure max block size isn't smaller than minimum allowed
Browse files Browse the repository at this point in the history
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 <npitre@baylibre.com>
  • Loading branch information
Nicolas Pitre authored and andrewboie committed Jul 3, 2019
1 parent fc4ca92 commit ace11bb
Show file tree
Hide file tree
Showing 3 changed files with 3 additions and 1 deletion.
1 change: 1 addition & 0 deletions include/kernel.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4159,6 +4159,7 @@ struct k_mem_pool {
* @req K-MPOOL-001 * @req K-MPOOL-001
*/ */
#define K_MEM_POOL_DEFINE(name, minsz, maxsz, nmax, align) \ #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 \ char __aligned(WB_UP(align)) _mpool_buf_##name[WB_UP(maxsz) * nmax \
+ _MPOOL_BITS_SIZE(maxsz, minsz, nmax)]; \ + _MPOOL_BITS_SIZE(maxsz, minsz, nmax)]; \
struct sys_mem_pool_lvl _mpool_lvls_##name[Z_MPOOL_LVLS(maxsz, minsz)]; \ struct sys_mem_pool_lvl _mpool_lvls_##name[Z_MPOOL_LVLS(maxsz, minsz)]; \
Expand Down
1 change: 1 addition & 0 deletions include/sys/mempool.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ struct sys_mem_pool_block {
* @param section Destination binary section for pool data * @param section Destination binary section for pool data
*/ */
#define SYS_MEM_POOL_DEFINE(name, ignored, minsz, maxsz, nmax, align, section) \ #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) \ char __aligned(WB_UP(align)) Z_GENERIC_SECTION(section) \
_mpool_buf_##name[WB_UP(maxsz) * nmax \ _mpool_buf_##name[WB_UP(maxsz) * nmax \
+ _MPOOL_BITS_SIZE(maxsz, minsz, nmax)]; \ + _MPOOL_BITS_SIZE(maxsz, minsz, nmax)]; \
Expand Down
2 changes: 1 addition & 1 deletion tests/kernel/queue/src/test_queue_contexts.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/**TESTPOINT: init via K_QUEUE_DEFINE*/ /**TESTPOINT: init via K_QUEUE_DEFINE*/
K_QUEUE_DEFINE(kqueue); 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); K_MEM_POOL_DEFINE(mem_pool_pass, 4, 64, 4, 4);


struct k_queue queue; struct k_queue queue;
Expand Down

0 comments on commit ace11bb

Please sign in to comment.