diff options
author | Kent Yoder <key@linux.vnet.ibm.com> | 2013-01-19 03:42:25 +0400 |
---|---|---|
committer | Kent Yoder <key@linux.vnet.ibm.com> | 2013-02-05 19:38:24 +0400 |
commit | 1fbc5e95356a4600fab3a04a82dc8bb49591aedd (patch) | |
tree | dd1a2e3d7370d592c58fdee2e983d2f80412bb07 | |
parent | d459335381eca1cb91fefb87021d3d172342e55a (diff) | |
download | linux-1fbc5e95356a4600fab3a04a82dc8bb49591aedd.tar.xz |
tpm_i2c_stm_st33: fix oops when i2c client is unavailable
When no i2c bus exists, user-space can cause an oops by triggering a
device probe through a message sent to an i2c "new_device" sysfs entry.
Adding a check for a NULL i2c client structure in the probe function
closes the hole.
This patch also fixes accessing the NULL client struct in the print
function call reporting the error.
Reported-by: Peter Hüwe <PeterHuewe@gmx.de>
Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com>
-rw-r--r-- | drivers/char/tpm/tpm_i2c_stm_st33.c | 16 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_i2c_stm_st33.h | 1 |
2 files changed, 11 insertions, 6 deletions
diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c index 24a33e08d0c6..36524ed8ada9 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.c +++ b/drivers/char/tpm/tpm_i2c_stm_st33.c @@ -658,7 +658,8 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) err = 0; if (client == NULL) { - dev_info(&client->dev, "client is NULL. exiting.\n"); + pr_info("%s: i2c client is NULL. Device not accessible.\n", + __func__); err = -ENODEV; goto end; } @@ -677,6 +678,13 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) } platform_data = client->dev.platform_data; + + if (!platform_data) { + dev_info(&client->dev, "chip not available\n"); + err = -ENODEV; + goto _tpm_clean_answer; + } + platform_data->tpm_i2c_buffer[0] = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); if (platform_data->tpm_i2c_buffer[0] == NULL) { @@ -759,7 +767,6 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) tpm_get_timeouts(chip); i2c_set_clientdata(client, chip); - platform_data->bChipF = false; dev_info(chip->dev, "TPM I2C Initialized\n"); return 0; @@ -779,7 +786,6 @@ _tpm_clean_response1: platform_data->tpm_i2c_buffer[0] = NULL; _tpm_clean_answer: tpm_remove_hardware(chip->dev); - platform_data->bChipF = true; end: pr_info("TPM I2C initialisation fail\n"); return err; @@ -803,8 +809,8 @@ static __devexit int tpm_st33_i2c_remove(struct i2c_client *client) gpio_free(pin_infos->io_serirq); gpio_free(pin_infos->io_lpcpd); - if (pin_infos->bChipF != true) - tpm_remove_hardware(chip->dev); + tpm_remove_hardware(chip->dev); + if (pin_infos->tpm_i2c_buffer[1] != NULL) { kzfree(pin_infos->tpm_i2c_buffer[1]); pin_infos->tpm_i2c_buffer[1] = NULL; diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.h b/drivers/char/tpm/tpm_i2c_stm_st33.h index 5862d0376bd8..439a43249aa6 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.h +++ b/drivers/char/tpm/tpm_i2c_stm_st33.h @@ -53,7 +53,6 @@ struct st33zp24_platform_data { int io_serirq; int io_lpcpd; struct i2c_client *client; - bool bChipF; u8 *tpm_i2c_buffer[2]; /* 0 Request 1 Response */ struct completion irq_detection; struct mutex lock; |