kunit: Fix possible memory leak in kunit_filter_suites()
If the outer layer for loop is iterated more than once and it fails not
in the first iteration, the filtered_suite and filtered_suite->test_cases
allocated in the last kunit_filter_attr_tests() in last inner for loop
is leaked.
So add a new free_filtered_suite err label and free the filtered_suite
and filtered_suite->test_cases so far. And change kmalloc_array of copy
to kcalloc to Clear the copy to make the kfree safe.
Fixes: 529534e8cb
("kunit: Add ability to filter attributes")
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
This commit is contained in:
parent
e44679515a
commit
24de14c98b
@ -157,10 +157,11 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
|
|||||||
struct kunit_suite_set filtered = {NULL, NULL};
|
struct kunit_suite_set filtered = {NULL, NULL};
|
||||||
struct kunit_glob_filter parsed_glob;
|
struct kunit_glob_filter parsed_glob;
|
||||||
struct kunit_attr_filter *parsed_filters = NULL;
|
struct kunit_attr_filter *parsed_filters = NULL;
|
||||||
|
struct kunit_suite * const *suites;
|
||||||
|
|
||||||
const size_t max = suite_set->end - suite_set->start;
|
const size_t max = suite_set->end - suite_set->start;
|
||||||
|
|
||||||
copy = kmalloc_array(max, sizeof(*filtered.start), GFP_KERNEL);
|
copy = kcalloc(max, sizeof(*filtered.start), GFP_KERNEL);
|
||||||
if (!copy) { /* won't be able to run anything, return an empty set */
|
if (!copy) { /* won't be able to run anything, return an empty set */
|
||||||
return filtered;
|
return filtered;
|
||||||
}
|
}
|
||||||
@ -195,7 +196,7 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
|
|||||||
parsed_glob.test_glob);
|
parsed_glob.test_glob);
|
||||||
if (IS_ERR(filtered_suite)) {
|
if (IS_ERR(filtered_suite)) {
|
||||||
*err = PTR_ERR(filtered_suite);
|
*err = PTR_ERR(filtered_suite);
|
||||||
goto free_parsed_filters;
|
goto free_filtered_suite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (filter_count > 0 && parsed_filters != NULL) {
|
if (filter_count > 0 && parsed_filters != NULL) {
|
||||||
@ -212,11 +213,11 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
|
|||||||
filtered_suite = new_filtered_suite;
|
filtered_suite = new_filtered_suite;
|
||||||
|
|
||||||
if (*err)
|
if (*err)
|
||||||
goto free_parsed_filters;
|
goto free_filtered_suite;
|
||||||
|
|
||||||
if (IS_ERR(filtered_suite)) {
|
if (IS_ERR(filtered_suite)) {
|
||||||
*err = PTR_ERR(filtered_suite);
|
*err = PTR_ERR(filtered_suite);
|
||||||
goto free_parsed_filters;
|
goto free_filtered_suite;
|
||||||
}
|
}
|
||||||
if (!filtered_suite)
|
if (!filtered_suite)
|
||||||
break;
|
break;
|
||||||
@ -231,6 +232,14 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
|
|||||||
filtered.start = copy_start;
|
filtered.start = copy_start;
|
||||||
filtered.end = copy;
|
filtered.end = copy;
|
||||||
|
|
||||||
|
free_filtered_suite:
|
||||||
|
if (*err) {
|
||||||
|
for (suites = copy_start; suites < copy; suites++) {
|
||||||
|
kfree((*suites)->test_cases);
|
||||||
|
kfree(*suites);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free_parsed_filters:
|
free_parsed_filters:
|
||||||
if (filter_count)
|
if (filter_count)
|
||||||
kfree(parsed_filters);
|
kfree(parsed_filters);
|
||||||
|
Loading…
Reference in New Issue
Block a user