* [PATCH] gpu/tests/buddy: Stop a test when gpu_buddy_init() fails
@ 2026-11-02 6:45 Yuqiang Sun
0 siblings, 0 replies; only message in thread
From: Yuqiang Sun @ 2026-11-02 6:45 UTC (permalink / raw)
To: matthew.auld, arunpravin.paneerselvam
Cc: joelagnelf, christian.koenig, mairacanal, airlied, simona,
dri-devel, linux-kernel
Three tests check gpu_buddy_init() with KUNIT_EXPECT_FALSE(), which only
records the failure, and go on to allocate from the allocator and to
call gpu_buddy_fini(). When gpu_buddy_init() fails, it has freed what it
allocated (or never allocated it), and the gpu_buddy is on the test's
stack, uninitialized, so the test then works on freed or garbage
pointers. The other tests in the file use KUNIT_ASSERT_FALSE(), which
stops the test case.
Use KUNIT_ASSERT_FALSE() in gpu_test_buddy_alloc_clear(),
gpu_test_buddy_alloc_contiguous() and gpu_test_buddy_alloc_limit() too.
In gpu_test_buddy_alloc_clear() each later call follows a
gpu_buddy_fini(), so stopping there leaves nothing allocated.
Found by kbound, a static analysis prototype for ownership mismatches at
kernel interfaces. Run-tested on QEMU (x86_64, KVM) with KASAN and the
suite as a module, with failslab limited to allocations under
gpu_buddy_init() and set to fail the first call's 1st to 5th allocation.
Before this patch, all 15 runs (three tests, five allocations) end in a
general protection fault, five of them after KASAN slab-use-after-free
reports in gpu_buddy_alloc_blocks() or __gpu_buddy_alloc_range(). With
it, each stops at the assertion, and the whole suite still passes
without injection.
Fixes: 932da861956a ("drm: selftest: convert drm_buddy selftest to KUnit")
Fixes: a64056bb5a32 ("drm/tests/drm_buddy: add alloc_contiguous test")
Fixes: c1696bf8d5f5 ("drm/tests: Add a test case for drm buddy clear allocation")
Signed-off-by: Yuqiang Sun <izaiahsun@gmail.com>
---
Notes:
The bug was found with kbound, a research static analysis prototype.
The patch, the changelog and the test setup were written with the help
of an AI coding assistant (Claude); I have reviewed and tested them as
described above.
The runs were on mainline d135ab453a74; the test file is the same there
and in drm-misc-next, which this patch is based on, except for an
unrelated hunk in gpu_test_buddy_alloc_contiguous().
drivers/gpu/tests/gpu_buddy_test.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/tests/gpu_buddy_test.c b/drivers/gpu/tests/gpu_buddy_test.c
index 2c6f1da1a6d1..e85d83e42bb7 100644
--- a/drivers/gpu/tests/gpu_buddy_test.c
+++ b/drivers/gpu/tests/gpu_buddy_test.c
@@ -975,7 +975,7 @@ static void gpu_test_buddy_alloc_clear(struct kunit *test)
LIST_HEAD(clean);
mm_size = SZ_4K << max_order;
- KUNIT_EXPECT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
+ KUNIT_ASSERT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
KUNIT_EXPECT_EQ(test, mm.max_order, max_order);
@@ -1035,7 +1035,7 @@ static void gpu_test_buddy_alloc_clear(struct kunit *test)
gpu_buddy_free_list(&mm, &dirty, 0);
gpu_buddy_fini(&mm);
- KUNIT_EXPECT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
+ KUNIT_ASSERT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
/*
* Create a new mm. Intentionally fragment the address space by creating
@@ -1095,7 +1095,7 @@ static void gpu_test_buddy_alloc_clear(struct kunit *test)
*/
mm_size = (SZ_4K << max_order) + (SZ_4K << (max_order - 2));
- KUNIT_EXPECT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
+ KUNIT_ASSERT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
KUNIT_EXPECT_EQ(test, mm.max_order, max_order);
KUNIT_ASSERT_FALSE_MSG(test, gpu_buddy_alloc_blocks(&mm, 0, SZ_4K << max_order,
4 * ps, ps, &allocated,
@@ -1123,7 +1123,7 @@ static void gpu_test_buddy_alloc_clear(struct kunit *test)
* and the split blocks should be merged back to their original size, so
* clear_avail must drop to 0.
*/
- KUNIT_EXPECT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
+ KUNIT_ASSERT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
KUNIT_EXPECT_EQ(test, mm.max_order, max_order);
n_pages = mm_size / ps;
@@ -1147,7 +1147,7 @@ static void gpu_test_buddy_alloc_clear(struct kunit *test)
* the split blocks should be merged back to their original size, so the
* whole address space (clear_avail) must equal mm_size.
*/
- KUNIT_EXPECT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
+ KUNIT_ASSERT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
KUNIT_EXPECT_EQ(test, mm.max_order, max_order);
for (i = 0; i < n_pages; i++) {
@@ -1176,7 +1176,7 @@ static void gpu_test_buddy_alloc_contiguous(struct kunit *test)
LIST_HEAD(right);
LIST_HEAD(allocated);
- KUNIT_EXPECT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
+ KUNIT_ASSERT_FALSE(test, gpu_buddy_init(&mm, mm_size, ps));
/*
* Idea is to fragment the address space by alternating block
@@ -1490,7 +1490,7 @@ static void gpu_test_buddy_alloc_limit(struct kunit *test)
LIST_HEAD(allocated);
struct gpu_buddy mm;
- KUNIT_EXPECT_FALSE(test, gpu_buddy_init(&mm, size, SZ_4K));
+ KUNIT_ASSERT_FALSE(test, gpu_buddy_init(&mm, size, SZ_4K));
KUNIT_EXPECT_EQ_MSG(test, mm.max_order, GPU_BUDDY_MAX_ORDER,
"mm.max_order(%d) != %d\n", mm.max_order,
base-commit: a1e63ab695ad76850ab9787b9eb6aab695dc2965
--
2.53.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-11-02 6:46 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-02 6:45 [PATCH] gpu/tests/buddy: Stop a test when gpu_buddy_init() fails Yuqiang Sun
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®