A bucket set is created with kmem_cache_create_usercopy(..., align = 0), so calculate_alignment() falls back to arch_slab_minalign(), typically 8 bytes. The general kmalloc caches it stands in for are created through create_boot_cache(), which starts from ARCH_KMALLOC_MINALIGN and raises it to the largest power-of-two divisor of the size: if (flags & SLAB_KMALLOC) align = max(align, 1U << (ffs(size) - 1)); This is only a problem when slab metadata is enabled with CONFIG_KASAN=y, CONFIG_SLUB_DEBUG_ON=y, or "slab_debug=...", because metadata changes the stride size off a power of two, for example: size 128: bucket align=8 size=224 | kmalloc align=128 size=384 size 512: bucket align=8 size=608 | kmalloc align=512 size=1536 size 2048: bucket align=8 size=2144 | kmalloc align=2048 size=6144 So bucket allocations will fail the IS_ALIGNED(p, ARCH_DMA_MINALIGN) check, potentially creating problems for non-coherent DMA situation. Take the alignment from the kmalloc cache being mirrored, which is where the size and the name suffix already come from, so a caller moving from kmalloc() keeps the alignment it had. Don't take an alignment from the caller instead. With CONFIG_SLAB_BUCKETS=n, or when kmem_buckets_create() fails, kmem_buckets_alloc() is served by the general kmalloc caches, which give kmalloc()'s alignment and no other. Fixes: b32801d1255be ("mm/slab: Introduce kmem_buckets_create() and family") Assisted-by: LLM Signed-off-by: Kees Cook --- mm/slab_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/slab_common.c b/mm/slab_common.c index f8bb70d76eb4..885aafa23da7 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -481,7 +481,8 @@ kmem_buckets *kmem_buckets_create(const char *name, unsigned int useroffset, if (WARN_ON(!cache_name)) goto fail; (*b)[aligned_idx] = kmem_cache_create_usercopy(cache_name, size, - 0, SLAB_NO_MERGE, cache_useroffset, + kmalloc_caches[KMALLOC_NORMAL][idx]->align, + SLAB_NO_MERGE, cache_useroffset, cache_usersize, NULL); kfree(cache_name); if (WARN_ON(!(*b)[aligned_idx])) -- 2.55.0