Skip to content

Commit 0665d7a

Browse files
yhuang-intelakpm00
authored andcommitted
resource, kunit: fix user-after-free in resource_test_region_intersects()
In resource_test_insert_resource(), the pointer is used in error message after kfree(). This is user-after-free. To fix this, we need to call kunit_add_action_or_reset() to schedule memory freeing after usage. But kunit_add_action_or_reset() itself may fail and free the memory. So, its return value should be checked and abort the test for failure. Then, we found that other usage of kunit_add_action_or_reset() in resource_test_region_intersects() needs to be fixed too. We fix all these user-after-free bugs in this patch. Link: https://lkml.kernel.org/r/[email protected] Fixes: 99185c1 ("resource, kunit: add test case for region_intersects()") Signed-off-by: "Huang, Ying" <[email protected]> Reported-by: Kees Bakker <[email protected]> Closes: https://lore.kernel.org/lkml/[email protected]/ Cc: Dan Williams <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: Bjorn Helgaas <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 3d5854d commit 0665d7a

File tree

1 file changed

+14
-4
lines changed

1 file changed

+14
-4
lines changed

kernel/resource_kunit.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ static void resource_test_intersection(struct kunit *test)
169169
#define RES_TEST_RAM3_SIZE SZ_1M
170170
#define RES_TEST_TOTAL_SIZE ((RES_TEST_WIN1_OFFSET + RES_TEST_WIN1_SIZE))
171171

172+
KUNIT_DEFINE_ACTION_WRAPPER(kfree_wrapper, kfree, const void *);
173+
172174
static void remove_free_resource(void *ctx)
173175
{
174176
struct resource *res = (struct resource *)ctx;
@@ -177,6 +179,14 @@ static void remove_free_resource(void *ctx)
177179
kfree(res);
178180
}
179181

182+
static void resource_test_add_action_or_abort(
183+
struct kunit *test, void (*action)(void *), void *ctx)
184+
{
185+
KUNIT_ASSERT_EQ_MSG(test, 0,
186+
kunit_add_action_or_reset(test, action, ctx),
187+
"Fail to add action");
188+
}
189+
180190
static void resource_test_request_region(struct kunit *test, struct resource *parent,
181191
resource_size_t start, resource_size_t size,
182192
const char *name, unsigned long flags)
@@ -185,7 +195,7 @@ static void resource_test_request_region(struct kunit *test, struct resource *pa
185195

186196
res = __request_region(parent, start, size, name, flags);
187197
KUNIT_ASSERT_NOT_NULL(test, res);
188-
kunit_add_action_or_reset(test, remove_free_resource, res);
198+
resource_test_add_action_or_abort(test, remove_free_resource, res);
189199
}
190200

191201
static void resource_test_insert_resource(struct kunit *test, struct resource *parent,
@@ -202,11 +212,11 @@ static void resource_test_insert_resource(struct kunit *test, struct resource *p
202212
res->end = start + size - 1;
203213
res->flags = flags;
204214
if (insert_resource(parent, res)) {
205-
kfree(res);
215+
resource_test_add_action_or_abort(test, kfree_wrapper, res);
206216
KUNIT_FAIL_AND_ABORT(test, "Fail to insert resource %pR\n", res);
207217
}
208218

209-
kunit_add_action_or_reset(test, remove_free_resource, res);
219+
resource_test_add_action_or_abort(test, remove_free_resource, res);
210220
}
211221

212222
static void resource_test_region_intersects(struct kunit *test)
@@ -220,7 +230,7 @@ static void resource_test_region_intersects(struct kunit *test)
220230
"test resources");
221231
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
222232
start = parent->start;
223-
kunit_add_action_or_reset(test, remove_free_resource, parent);
233+
resource_test_add_action_or_abort(test, remove_free_resource, parent);
224234

225235
resource_test_request_region(test, parent, start + RES_TEST_RAM0_OFFSET,
226236
RES_TEST_RAM0_SIZE, "Test System RAM 0", flags);

0 commit comments

Comments
 (0)