]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ipmi: Fix some error cleanup issues
authorCorey Minyard <cminyard@mvista.com>
Wed, 28 Feb 2018 14:09:49 +0000 (08:09 -0600)
committerCorey Minyard <cminyard@mvista.com>
Wed, 7 Mar 2018 01:47:17 +0000 (19:47 -0600)
device_remove_group() was called on any cleanup, even if the
device attrs had not been added yet.  That can occur in certain
error scenarios, so add a flag to know if it has been added.

Also make sure we remove the dev if we added it ourselves.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: stable@vger.kernel.org # 4.15
Cc: Laura Abbott <labbott@redhat.com>
Tested-by: Bill Perkins <wmp@grnwood.net>
drivers/char/ipmi/ipmi_si_intf.c

index 5141ccf0b9581c6c356af731305afc0e254bea2e..2b9f434775d4dfeb8101a56a9c665dfd76d737f9 100644 (file)
@@ -232,6 +232,9 @@ struct smi_info {
        /* Default driver model device. */
        struct platform_device *pdev;
 
+       /* Have we added the device group to the device? */
+       bool dev_group_added;
+
        /* Counters and things for the proc filesystem. */
        atomic_t stats[SI_NUM_STATS];
 
@@ -2007,8 +2010,8 @@ int ipmi_si_add_smi(struct si_sm_io *io)
        if (initialized) {
                rv = try_smi_init(new_smi);
                if (rv) {
-                       mutex_unlock(&smi_infos_lock);
                        cleanup_one_si(new_smi);
+                       mutex_unlock(&smi_infos_lock);
                        return rv;
                }
        }
@@ -2167,6 +2170,7 @@ static int try_smi_init(struct smi_info *new_smi)
                        rv);
                goto out_err_stop_timer;
        }
+       new_smi->dev_group_added = true;
 
        rv = ipmi_register_smi(&handlers,
                               new_smi,
@@ -2220,7 +2224,10 @@ static int try_smi_init(struct smi_info *new_smi)
        return 0;
 
 out_err_remove_attrs:
-       device_remove_group(new_smi->io.dev, &ipmi_si_dev_attr_group);
+       if (new_smi->dev_group_added) {
+               device_remove_group(new_smi->io.dev, &ipmi_si_dev_attr_group);
+               new_smi->dev_group_added = false;
+       }
        dev_set_drvdata(new_smi->io.dev, NULL);
 
 out_err_stop_timer:
@@ -2268,6 +2275,7 @@ out_err:
                else
                        platform_device_put(new_smi->pdev);
                new_smi->pdev = NULL;
+               new_smi->io.dev = NULL;
        }
 
        kfree(init_name);
@@ -2364,8 +2372,10 @@ static void cleanup_one_si(struct smi_info *to_clean)
                }
        }
 
-       device_remove_group(to_clean->io.dev, &ipmi_si_dev_attr_group);
-       dev_set_drvdata(to_clean->io.dev, NULL);
+       if (to_clean->dev_group_added)
+               device_remove_group(to_clean->io.dev, &ipmi_si_dev_attr_group);
+       if (to_clean->io.dev)
+               dev_set_drvdata(to_clean->io.dev, NULL);
 
        list_del(&to_clean->link);