Hi all, This series fixes a per-cpu hold counter underflow in the AppArmor buffer cache. Under high-frequency execve workloads with AppArmor enabled, cache->hold can wrap to UINT_MAX, preventing buffers from returning to the global list and forcing repeated kmalloc(aa_g_path_max) allocations.
Summary: On high-frequency execve workloads with AppArmor enabled, the per-CPU buffer cache can enter a pathological state: aa_get_buffer() decrements hold even when it is already zero, causing an unsigned underflow. The resulting huge hold value prevents aa_put_buffer() from refilling the global list, which starves other CPUs and forces repeated kmalloc(aa_g_path_max) allocations. Because the AppArmor pool does not shrink, this accumulates into large kmalloc-8k slab growth over time. Repro (QEMU TCG, 4 vCPU, 1 GiB RAM, v6.16): - Unpatched: kmalloc-8k objects grow 12->16 in 120s (run1), 16->20 in 120s (run2) - Patched: kmalloc-8k stays at 12 for 120s Notes: This fix targets the observed underflow mechanism without changing the overall AppArmor buffer pool design. Happy to provide the reproduction script and logs on request. Thanks, Zhengmian Hu Zhengmian Hu (1): apparmor: avoid per-cpu hold underflow in aa_get_buffer security/apparmor/lsm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -- 2.52.0
