From b5ba09ed589c4e15f2b60c59f55da84e06689631 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 7 Feb 2022 10:32:00 +0100 Subject: [PATCH] BUG/MEDIUM: pools: ensure items are always large enough for the pool_cache_item With the introduction of DEBUG_POOL_TRACING in 2.6-dev with commit add43fa43 ("DEBUG: pools: add new build option DEBUG_POOL_TRACING"), small pools might be too short to store both the pool_cache_item struct and the caller location, resulting in memory corruption and crashes when this debug option is used. What happens here is that the way the size is calculated is by considering that the POOL_EXTRA part is only used while the object is in use, but this is not true anymore for the caller's pointer which must absolutely be placed after the pool_cache_item. This patch makes sure that the caller part will always start after the pool_cache_item and that the allocation will always be sufficent. This is only tagged medium because the debug option is new and unlikely to be used unless requested by a developer. No backport is needed. --- src/pool.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/pool.c b/src/pool.c index 3fda2fbd8c..04677ec9ab 100644 --- a/src/pool.c +++ b/src/pool.c @@ -179,6 +179,15 @@ struct pool_head *create_pool(char *name, unsigned int size, unsigned int flags) size = ((size + POOL_EXTRA + align - 1) & -align) - POOL_EXTRA; } +#ifdef CONFIG_HAP_POOLS + /* we'll store two lists there, we need the room for this. This is + * guaranteed by the test above, except if MEM_F_EXACT is set, or if + * the only EXTRA part is in fact the one that's stored in the cache + * in addition to the pci struct. + */ + if (size + POOL_EXTRA - POOL_EXTRA_CALLER < sizeof(struct pool_cache_item)) + size = sizeof(struct pool_cache_item) + POOL_EXTRA_CALLER - POOL_EXTRA; +#endif /* TODO: thread: we do not lock pool list for now because all pools are * created during HAProxy startup (so before threads creation) */ start = &pools; -- 2.39.5