diff options
author | Corey Minyard <cminyard@mvista.com> | 2018-02-28 08:09:49 -0600 |
---|---|---|
committer | Corey Minyard <cminyard@mvista.com> | 2018-03-06 19:47:17 -0600 |
commit | cc095f0ac1f7c200e51a5c2a78a43c9f42049dbb (patch) | |
tree | cea28774af6227161791960af5b705b0999d9c88 /drivers/char | |
parent | 243ac21035176ac9692c1308a9f3b8f6a4e5d733 (diff) | |
download | linux-stable-cc095f0ac1f7c200e51a5c2a78a43c9f42049dbb.tar.gz linux-stable-cc095f0ac1f7c200e51a5c2a78a43c9f42049dbb.tar.bz2 linux-stable-cc095f0ac1f7c200e51a5c2a78a43c9f42049dbb.zip |
ipmi: Fix some error cleanup issues
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>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 5141ccf0b958..2b9f434775d4 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -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); |