[PATCH v2 3/3] slab: test zero-size allocations in slub_kunit
From: Karl Mehltretter
Date: Tue Aug 11 2026 - 10:23:37 EST
Add KUnit coverage for the zero-size allocation contract, including
ZERO_SIZE_PTR alignment and exact ZERO_OR_NULL_PTR() matching.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@xxxxxxxxx>
---
lib/tests/slub_kunit.c | 43 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/lib/tests/slub_kunit.c b/lib/tests/slub_kunit.c
index fa6d31dbca166..a02fc6b401e3e 100644
--- a/lib/tests/slub_kunit.c
+++ b/lib/tests/slub_kunit.c
@@ -380,6 +380,48 @@ static void test_kmalloc_kfree_nolock(struct kunit *test)
}
#endif
+static void test_zero_size_alloc(struct kunit *test)
+{
+ unsigned long zsp = (unsigned long)ZERO_SIZE_PTR;
+ void *p, *r;
+
+ static_assert((unsigned long)ZERO_SIZE_PTR % ARCH_KMALLOC_MINALIGN == 0);
+
+ p = kmalloc(0, GFP_KERNEL);
+ KUNIT_EXPECT_PTR_EQ(test, p, ZERO_SIZE_PTR);
+ KUNIT_EXPECT_EQ(test, ksize(p), 0);
+ kfree(p);
+
+ KUNIT_EXPECT_PTR_EQ(test, kzalloc(0, GFP_KERNEL), ZERO_SIZE_PTR);
+ KUNIT_EXPECT_PTR_EQ(test, kmalloc_array(0, 8, GFP_KERNEL), ZERO_SIZE_PTR);
+ KUNIT_EXPECT_PTR_EQ(test, kcalloc(4, 0, GFP_KERNEL), ZERO_SIZE_PTR);
+
+ p = kvmalloc(0, GFP_KERNEL);
+ KUNIT_EXPECT_PTR_EQ(test, p, ZERO_SIZE_PTR);
+ kvfree(p);
+
+ p = krealloc(NULL, 0, GFP_KERNEL);
+ KUNIT_EXPECT_PTR_EQ(test, p, ZERO_SIZE_PTR);
+ r = krealloc(p, 64, GFP_KERNEL);
+ KUNIT_EXPECT_FALSE(test, ZERO_OR_NULL_PTR(r));
+ p = krealloc(r, 0, GFP_KERNEL);
+ KUNIT_EXPECT_PTR_EQ(test, p, ZERO_SIZE_PTR);
+ kfree(p);
+
+ /* Only NULL and the zero-size sentinel match. */
+ KUNIT_EXPECT_TRUE(test, ZERO_OR_NULL_PTR(NULL));
+ KUNIT_EXPECT_TRUE(test, ZERO_OR_NULL_PTR(ZERO_SIZE_PTR));
+ KUNIT_EXPECT_FALSE(test, ZERO_OR_NULL_PTR((void *)1));
+ KUNIT_EXPECT_FALSE(test, ZERO_OR_NULL_PTR((void *)(zsp - 1)));
+ KUNIT_EXPECT_FALSE(test, ZERO_OR_NULL_PTR((void *)(zsp + 1)));
+ KUNIT_EXPECT_FALSE(test, ZERO_OR_NULL_PTR((void *)(zsp * 2)));
+
+ /* freeing the sentinel must stay a no-op */
+ kfree(ZERO_SIZE_PTR);
+ kfree_sensitive(ZERO_SIZE_PTR);
+ kvfree(ZERO_SIZE_PTR);
+}
+
static int test_init(struct kunit *test)
{
slab_errors = 0;
@@ -404,6 +446,7 @@ static struct kunit_case test_cases[] = {
KUNIT_CASE(test_kfree_rcu_wq_destroy),
KUNIT_CASE(test_leak_destroy),
KUNIT_CASE(test_krealloc_redzone_zeroing),
+ KUNIT_CASE(test_zero_size_alloc),
#ifdef CONFIG_PERF_EVENTS
KUNIT_CASE_SLOW(test_kmalloc_kfree_nolock),
#endif
--
2.53.0