kernel/mem_pool: Correct n_levels computation for small blocks

The new mem pool implementation has a hard minimum block size of 8
bytes, but the macros to statically compute the number of levels
didn't clamp, leading to invalid small allocations being allowed,
which would then corrupt the list pointers of nearby blocks and/or
overflow the buffer entirely and corrupt other memory.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2017-11-13 14:59:13 -08:00 committed by Andrew Boie
commit 8cf7ff5e2a

View file

@ -3532,23 +3532,28 @@ struct k_mem_pool {
#define _MPOOL_HAVE_LVL(max, min, l) (((max) >> (2*(l))) >= (min) ? 1 : 0)
#define _MPOOL_LVLS(maxsz, minsz) \
(_MPOOL_HAVE_LVL(maxsz, minsz, 0) + \
_MPOOL_HAVE_LVL(maxsz, minsz, 1) + \
_MPOOL_HAVE_LVL(maxsz, minsz, 2) + \
_MPOOL_HAVE_LVL(maxsz, minsz, 3) + \
_MPOOL_HAVE_LVL(maxsz, minsz, 4) + \
_MPOOL_HAVE_LVL(maxsz, minsz, 5) + \
_MPOOL_HAVE_LVL(maxsz, minsz, 6) + \
_MPOOL_HAVE_LVL(maxsz, minsz, 7) + \
_MPOOL_HAVE_LVL(maxsz, minsz, 8) + \
_MPOOL_HAVE_LVL(maxsz, minsz, 9) + \
_MPOOL_HAVE_LVL(maxsz, minsz, 10) + \
_MPOOL_HAVE_LVL(maxsz, minsz, 11) + \
_MPOOL_HAVE_LVL(maxsz, minsz, 12) + \
_MPOOL_HAVE_LVL(maxsz, minsz, 13) + \
_MPOOL_HAVE_LVL(maxsz, minsz, 14) + \
_MPOOL_HAVE_LVL(maxsz, minsz, 15))
#define __MPOOL_LVLS(maxsz, minsz) \
(_MPOOL_HAVE_LVL((maxsz), (minsz), 0) + \
_MPOOL_HAVE_LVL((maxsz), (minsz), 1) + \
_MPOOL_HAVE_LVL((maxsz), (minsz), 2) + \
_MPOOL_HAVE_LVL((maxsz), (minsz), 3) + \
_MPOOL_HAVE_LVL((maxsz), (minsz), 4) + \
_MPOOL_HAVE_LVL((maxsz), (minsz), 5) + \
_MPOOL_HAVE_LVL((maxsz), (minsz), 6) + \
_MPOOL_HAVE_LVL((maxsz), (minsz), 7) + \
_MPOOL_HAVE_LVL((maxsz), (minsz), 8) + \
_MPOOL_HAVE_LVL((maxsz), (minsz), 9) + \
_MPOOL_HAVE_LVL((maxsz), (minsz), 10) + \
_MPOOL_HAVE_LVL((maxsz), (minsz), 11) + \
_MPOOL_HAVE_LVL((maxsz), (minsz), 12) + \
_MPOOL_HAVE_LVL((maxsz), (minsz), 13) + \
_MPOOL_HAVE_LVL((maxsz), (minsz), 14) + \
_MPOOL_HAVE_LVL((maxsz), (minsz), 15))
#define _MPOOL_MINBLK sizeof(sys_dnode_t)
#define _MPOOL_LVLS(max, min) \
__MPOOL_LVLS((max), (min) >= _MPOOL_MINBLK ? (min) : _MPOOL_MINBLK)
/* Rounds the needed bits up to integer multiples of u32_t */
#define _MPOOL_LBIT_WORDS_UNCLAMPED(n_max, l) \