summaryrefslogtreecommitdiffstats
path: root/lib/kunit
diff options
context:
space:
mode:
authorJinjie Ruan <ruanjinjie@huawei.com>2023-09-27 17:03:49 +0800
committerShuah Khan <skhan@linuxfoundation.org>2023-09-28 08:51:02 -0600
commit24de14c98b37ea40a7e493dfd0d93b400b6efbca (patch)
tree633f2714f009c9b0482f9acaf75f9e0ae74b713c /lib/kunit
parente44679515a7b803cf0143dc9de3d2ecbe907f939 (diff)
downloadlinux-stable-24de14c98b37ea40a7e493dfd0d93b400b6efbca.tar.gz
linux-stable-24de14c98b37ea40a7e493dfd0d93b400b6efbca.tar.bz2
linux-stable-24de14c98b37ea40a7e493dfd0d93b400b6efbca.zip
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: 529534e8cba3 ("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>
Diffstat (limited to 'lib/kunit')
-rw-r--r--lib/kunit/executor.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c
index 9358ed2df839..1236b3cd2fbb 100644
--- a/lib/kunit/executor.c
+++ b/lib/kunit/executor.c
@@ -157,10 +157,11 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
struct kunit_suite_set filtered = {NULL, NULL};
struct kunit_glob_filter parsed_glob;
struct kunit_attr_filter *parsed_filters = NULL;
+ struct kunit_suite * const *suites;
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 */
return filtered;
}
@@ -195,7 +196,7 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
parsed_glob.test_glob);
if (IS_ERR(filtered_suite)) {
*err = PTR_ERR(filtered_suite);
- goto free_parsed_filters;
+ goto free_filtered_suite;
}
}
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;
if (*err)
- goto free_parsed_filters;
+ goto free_filtered_suite;
if (IS_ERR(filtered_suite)) {
*err = PTR_ERR(filtered_suite);
- goto free_parsed_filters;
+ goto free_filtered_suite;
}
if (!filtered_suite)
break;
@@ -231,6 +232,14 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
filtered.start = copy_start;
filtered.end = copy;
+free_filtered_suite:
+ if (*err) {
+ for (suites = copy_start; suites < copy; suites++) {
+ kfree((*suites)->test_cases);
+ kfree(*suites);
+ }
+ }
+
free_parsed_filters:
if (filter_count)
kfree(parsed_filters);