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 <[email protected]>
---
 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


Reply via email to