kunit: fix uninitialized variables bug in attributes filtering
authorRae Moar <rmoar@google.com>
Thu, 3 Aug 2023 19:36:35 +0000 (19:36 +0000)
committerShuah Khan <skhan@linuxfoundation.org>
Fri, 4 Aug 2023 19:41:55 +0000 (13:41 -0600)
Fix smatch warnings regarding uninitialized variables in the filtering
patch of the new KUnit Attributes feature.

Fixes: 529534e8cba3 ("kunit: Add ability to filter attributes")
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Closes: https://lore.kernel.org/r/202307270610.s0w4NKEn-lkp@intel.com/
Signed-off-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
lib/kunit/attributes.c
lib/kunit/executor.c
lib/kunit/executor_test.c

index d37c40c0ce4f582059153d3db865ce9fb22c0037..5e3034b6be990b2bbd8a520a62839c978e272506 100644 (file)
@@ -102,7 +102,7 @@ static int int_filter(long val, const char *op, int input, int *err)
 static int attr_enum_filter(void *attr, const char *input, int *err,
                const char * const str_list[], int max)
 {
-       int i, j, input_int;
+       int i, j, input_int = -1;
        long test_val = (long)attr;
        const char *input_val = NULL;
 
@@ -124,7 +124,7 @@ static int attr_enum_filter(void *attr, const char *input, int *err,
                        input_int = j;
        }
 
-       if (!input_int) {
+       if (input_int < 0) {
                *err = -EINVAL;
                pr_err("kunit executor: invalid filter input: %s\n", input);
                return false;
@@ -186,8 +186,10 @@ static void *attr_module_get(void *test_or_suite, bool is_test)
        // Suites get their module attribute from their first test_case
        if (test)
                return ((void *) test->module_name);
-       else
+       else if (kunit_suite_num_test_cases(suite) > 0)
                return ((void *) suite->test_cases[0].module_name);
+       else
+               return (void *) "";
 }
 
 /* List of all Test Attributes */
@@ -221,7 +223,7 @@ const char *kunit_attr_filter_name(struct kunit_attr_filter filter)
 void kunit_print_attr(void *test_or_suite, bool is_test, unsigned int test_level)
 {
        int i;
-       bool to_free;
+       bool to_free = false;
        void *attr;
        const char *attr_name, *attr_str;
        struct kunit_suite *suite = is_test ? NULL : test_or_suite;
@@ -255,7 +257,7 @@ void kunit_print_attr(void *test_or_suite, bool is_test, unsigned int test_level
 
 int kunit_get_filter_count(char *input)
 {
-       int i, comma_index, count = 0;
+       int i, comma_index = 0, count = 0;
 
        for (i = 0; input[i]; i++) {
                if (input[i] == ',') {
@@ -272,7 +274,7 @@ int kunit_get_filter_count(char *input)
 struct kunit_attr_filter kunit_next_attr_filter(char **filters, int *err)
 {
        struct kunit_attr_filter filter = {};
-       int i, j, comma_index, new_start_index;
+       int i, j, comma_index = 0, new_start_index = 0;
        int op_index = -1, attr_index = -1;
        char op;
        char *input = *filters;
@@ -316,7 +318,7 @@ struct kunit_attr_filter kunit_next_attr_filter(char **filters, int *err)
                filter.attr = &kunit_attr_list[attr_index];
        }
 
-       if (comma_index) {
+       if (comma_index > 0) {
                input[comma_index] = '\0';
                filter.input = input + op_index;
                input = input + new_start_index;
@@ -356,31 +358,22 @@ struct kunit_suite *kunit_filter_attr_tests(const struct kunit_suite *const suit
 
        /* Save filtering result on default value */
        default_result = filter.attr->filter(filter.attr->attr_default, filter.input, err);
-       if (*err) {
-               kfree(copy);
-               kfree(filtered);
-               return NULL;
-       }
+       if (*err)
+               goto err;
 
        /* Save suite attribute value and filtering result on that value */
        suite_val = filter.attr->get_attr((void *)suite, false);
        suite_result = filter.attr->filter(suite_val, filter.input, err);
-       if (*err) {
-               kfree(copy);
-               kfree(filtered);
-               return NULL;
-       }
+       if (*err)
+               goto err;
 
        /* For each test case, save test case if passes filtering. */
        kunit_suite_for_each_test_case(suite, test_case) {
                test_val = filter.attr->get_attr((void *) test_case, true);
                test_result = filter.attr->filter(filter.attr->get_attr(test_case, true),
                                filter.input, err);
-               if (*err) {
-                       kfree(copy);
-                       kfree(filtered);
-                       return NULL;
-               }
+               if (*err)
+                       goto err;
 
                /*
                 * If attribute value of test case is set, filter on that value.
@@ -406,7 +399,8 @@ struct kunit_suite *kunit_filter_attr_tests(const struct kunit_suite *const suit
                }
        }
 
-       if (n == 0) {
+err:
+       if (n == 0 || *err) {
                kfree(copy);
                kfree(filtered);
                return NULL;
index 481901d245d0e6ae399abf799197cd5daf2234c0..dc295150c4e5718ba6ebdee22e26d1ad5f9c44f8 100644 (file)
@@ -127,19 +127,18 @@ static struct suite_set kunit_filter_suites(const struct suite_set *suite_set,
 {
        int i, j, k;
        int filter_count = 0;
-       struct kunit_suite **copy, *filtered_suite, *new_filtered_suite;
-       struct suite_set filtered;
+       struct kunit_suite **copy, **copy_start, *filtered_suite, *new_filtered_suite;
+       struct suite_set filtered = {NULL, NULL};
        struct kunit_glob_filter parsed_glob;
-       struct kunit_attr_filter *parsed_filters;
+       struct kunit_attr_filter *parsed_filters = NULL;
 
        const size_t max = suite_set->end - suite_set->start;
 
        copy = kmalloc_array(max, sizeof(*filtered.start), GFP_KERNEL);
-       filtered.start = copy;
        if (!copy) { /* won't be able to run anything, return an empty set */
-               filtered.end = copy;
                return filtered;
        }
+       copy_start = copy;
 
        if (filter_glob)
                kunit_parse_glob_filter(&parsed_glob, filter_glob);
@@ -147,7 +146,11 @@ static struct suite_set kunit_filter_suites(const struct suite_set *suite_set,
        /* Parse attribute filters */
        if (filters) {
                filter_count = kunit_get_filter_count(filters);
-               parsed_filters = kcalloc(filter_count + 1, sizeof(*parsed_filters), GFP_KERNEL);
+               parsed_filters = kcalloc(filter_count, sizeof(*parsed_filters), GFP_KERNEL);
+               if (!parsed_filters) {
+                       kfree(copy);
+                       return filtered;
+               }
                for (j = 0; j < filter_count; j++)
                        parsed_filters[j] = kunit_next_attr_filter(&filters, err);
                if (*err)
@@ -166,7 +169,7 @@ static struct suite_set kunit_filter_suites(const struct suite_set *suite_set,
                                goto err;
                        }
                }
-               if (filter_count) {
+               if (filter_count > 0 && parsed_filters != NULL) {
                        for (k = 0; k < filter_count; k++) {
                                new_filtered_suite = kunit_filter_attr_tests(filtered_suite,
                                                parsed_filters[k], filter_action, err);
@@ -195,6 +198,7 @@ static struct suite_set kunit_filter_suites(const struct suite_set *suite_set,
 
                *copy++ = filtered_suite;
        }
+       filtered.start = copy_start;
        filtered.end = copy;
 
 err:
index 01280cb8d45186910b097e512658b5177155c2cf..3e0a1c99cb4e8d5e0875e6dbc98d5a5f75762796 100644 (file)
@@ -119,7 +119,7 @@ static void parse_filter_attr_test(struct kunit *test)
        filter_count = kunit_get_filter_count(filters);
        KUNIT_EXPECT_EQ(test, filter_count, 2);
 
-       parsed_filters = kunit_kcalloc(test, filter_count + 1, sizeof(*parsed_filters),
+       parsed_filters = kunit_kcalloc(test, filter_count, sizeof(*parsed_filters),
                        GFP_KERNEL);
        for (j = 0; j < filter_count; j++) {
                parsed_filters[j] = kunit_next_attr_filter(&filters, &err);