media: atomisp: fix bad usage at error handling logic
authorMauro Carvalho Chehab <mchehab@kernel.org>
Mon, 14 Mar 2022 17:11:38 +0000 (18:11 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Fri, 18 Mar 2022 04:58:35 +0000 (05:58 +0100)
As warned by sparse:
atomisp: drivers/staging/media/atomisp/pci/atomisp_acc.c:508 atomisp_acc_load_extensions() warn: iterator used outside loop: 'acc_fw'

The acc_fw interactor is used outside the loop, at the error handling
logic. On most cases, this is actually safe there, but, if
atomisp_css_set_acc_parameters() has an error, an attempt to use it
will pick an invalid value for acc_fw.

Reported-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/staging/media/atomisp/pci/atomisp_acc.c

index 9a17518..28cb271 100644 (file)
@@ -439,6 +439,18 @@ int atomisp_acc_s_mapped_arg(struct atomisp_sub_device *asd,
        return 0;
 }
 
+static void atomisp_acc_unload_some_extensions(struct atomisp_sub_device *asd,
+                                             int i,
+                                             struct atomisp_acc_fw *acc_fw)
+{
+       while (--i >= 0) {
+               if (acc_fw->flags & acc_flag_to_pipe[i].flag) {
+                       atomisp_css_unload_acc_extension(asd, acc_fw->fw,
+                                                        acc_flag_to_pipe[i].pipe_id);
+               }
+       }
+}
+
 /*
  * Appends the loaded acceleration binary extensions to the
  * current ISP mode. Must be called just before sh_css_start().
@@ -479,16 +491,20 @@ int atomisp_acc_load_extensions(struct atomisp_sub_device *asd)
                                                                     acc_fw->fw,
                                                                     acc_flag_to_pipe[i].pipe_id,
                                                                     acc_fw->type);
-                               if (ret)
+                               if (ret) {
+                                       atomisp_acc_unload_some_extensions(asd, i, acc_fw);
                                        goto error;
+                               }
 
                                ext_loaded = true;
                        }
                }
 
                ret = atomisp_css_set_acc_parameters(acc_fw);
-               if (ret < 0)
+               if (ret < 0) {
+                       atomisp_acc_unload_some_extensions(asd, i, acc_fw);
                        goto error;
+               }
        }
 
        if (!ext_loaded)
@@ -497,6 +513,7 @@ int atomisp_acc_load_extensions(struct atomisp_sub_device *asd)
        ret = atomisp_css_update_stream(asd);
        if (ret) {
                dev_err(isp->dev, "%s: update stream failed.\n", __func__);
+               atomisp_acc_unload_extensions(asd);
                goto error;
        }
 
@@ -504,13 +521,6 @@ int atomisp_acc_load_extensions(struct atomisp_sub_device *asd)
        return 0;
 
 error:
-       while (--i >= 0) {
-               if (acc_fw->flags & acc_flag_to_pipe[i].flag) {
-                       atomisp_css_unload_acc_extension(asd, acc_fw->fw,
-                                                        acc_flag_to_pipe[i].pipe_id);
-               }
-       }
-
        list_for_each_entry_continue_reverse(acc_fw, &asd->acc.fw, list) {
                if (acc_fw->type != ATOMISP_ACC_FW_LOAD_TYPE_OUTPUT &&
                    acc_fw->type != ATOMISP_ACC_FW_LOAD_TYPE_VIEWFINDER)