]> git.itanic.dy.fi Git - linux-stable/commitdiff
ipmi: Fix some error cleanup issues
authorCorey Minyard <cminyard@mvista.com>
Wed, 28 Feb 2018 14:09:49 +0000 (08:09 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Apr 2018 06:55:08 +0000 (08:55 +0200)
commit cc095f0ac1f7c200e51a5c2a78a43c9f42049dbb upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/char/ipmi/ipmi_si_intf.c

index 7499b0cd8326f701a8fd136d70cd9f07c3fc3162..c33e579d89114005a14017f972fd62ade3a458d5 100644 (file)
@@ -252,6 +252,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];
 
@@ -2025,8 +2028,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;
                }
        }
@@ -2185,6 +2188,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,
@@ -2238,7 +2242,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:
@@ -2286,6 +2293,7 @@ static int try_smi_init(struct smi_info *new_smi)
                else
                        platform_device_put(new_smi->pdev);
                new_smi->pdev = NULL;
+               new_smi->io.dev = NULL;
        }
 
        kfree(init_name);
@@ -2382,8 +2390,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);