summaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorMian Yousaf Kaukab <ykaukab@suse.de>2021-12-08 10:32:39 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-12-29 12:23:36 +0100
commit8efd6a3391f7b0b19fb0c38e50add06ca30c94af (patch)
treedf972246ec0217a072877cb7ab44eeeac9ad0c9b /drivers/char
parentcd24bafefc17947532008c3667637aee7471d7a8 (diff)
downloadlinux-stable-8efd6a3391f7b0b19fb0c38e50add06ca30c94af.tar.gz
linux-stable-8efd6a3391f7b0b19fb0c38e50add06ca30c94af.tar.bz2
linux-stable-8efd6a3391f7b0b19fb0c38e50add06ca30c94af.zip
ipmi: ssif: initialize ssif_info->client early
commit 34f35f8f14bc406efc06ee4ff73202c6fd245d15 upstream. During probe ssif_info->client is dereferenced in error path. However, it is set when some of the error checking has already been done. This causes following kernel crash if an error path is taken: [ 30.645593][ T674] ipmi_ssif 0-000e: ipmi_ssif: Not probing, Interface already present [ 30.657616][ T674] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000088 ... [ 30.657723][ T674] pc : __dev_printk+0x28/0xa0 [ 30.657732][ T674] lr : _dev_err+0x7c/0xa0 ... [ 30.657772][ T674] Call trace: [ 30.657775][ T674] __dev_printk+0x28/0xa0 [ 30.657778][ T674] _dev_err+0x7c/0xa0 [ 30.657781][ T674] ssif_probe+0x548/0x900 [ipmi_ssif 62ce4b08badc1458fd896206d9ef69a3c31f3d3e] [ 30.657791][ T674] i2c_device_probe+0x37c/0x3c0 ... Initialize ssif_info->client before any error path can be taken. Clear i2c_client data in the error path to prevent the dangling pointer from leaking. Fixes: c4436c9149c5 ("ipmi_ssif: avoid registering duplicate ssif interface") Cc: stable@vger.kernel.org # 5.4.x Suggested-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Mian Yousaf Kaukab <ykaukab@suse.de> Message-Id: <20211208093239.4432-1-ykaukab@suse.de> Signed-off-by: Corey Minyard <cminyard@mvista.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/ipmi/ipmi_ssif.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
index 8ac390c2b514..bb42a1c92cae 100644
--- a/drivers/char/ipmi/ipmi_ssif.c
+++ b/drivers/char/ipmi/ipmi_ssif.c
@@ -1704,6 +1704,9 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
}
}
+ ssif_info->client = client;
+ i2c_set_clientdata(client, ssif_info);
+
rv = ssif_check_and_remove(client, ssif_info);
/* If rv is 0 and addr source is not SI_ACPI, continue probing */
if (!rv && ssif_info->addr_source == SI_ACPI) {
@@ -1724,9 +1727,6 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
ipmi_addr_src_to_str(ssif_info->addr_source),
client->addr, client->adapter->name, slave_addr);
- ssif_info->client = client;
- i2c_set_clientdata(client, ssif_info);
-
/* Now check for system interface capabilities */
msg[0] = IPMI_NETFN_APP_REQUEST << 2;
msg[1] = IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_CMD;
@@ -1926,6 +1926,7 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
dev_err(&ssif_info->client->dev,
"Unable to start IPMI SSIF: %d\n", rv);
+ i2c_set_clientdata(client, NULL);
kfree(ssif_info);
}
kfree(resp);