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>
This commit is contained in:
Родитель
d459335381
Коммит
1fbc5e9535
|
@ -658,7 +658,8 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
if (client == NULL) {
|
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;
|
err = -ENODEV;
|
||||||
goto end;
|
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;
|
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] =
|
platform_data->tpm_i2c_buffer[0] =
|
||||||
kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
|
kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
|
||||||
if (platform_data->tpm_i2c_buffer[0] == NULL) {
|
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);
|
tpm_get_timeouts(chip);
|
||||||
|
|
||||||
i2c_set_clientdata(client, chip);
|
i2c_set_clientdata(client, chip);
|
||||||
platform_data->bChipF = false;
|
|
||||||
|
|
||||||
dev_info(chip->dev, "TPM I2C Initialized\n");
|
dev_info(chip->dev, "TPM I2C Initialized\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -779,7 +786,6 @@ _tpm_clean_response1:
|
||||||
platform_data->tpm_i2c_buffer[0] = NULL;
|
platform_data->tpm_i2c_buffer[0] = NULL;
|
||||||
_tpm_clean_answer:
|
_tpm_clean_answer:
|
||||||
tpm_remove_hardware(chip->dev);
|
tpm_remove_hardware(chip->dev);
|
||||||
platform_data->bChipF = true;
|
|
||||||
end:
|
end:
|
||||||
pr_info("TPM I2C initialisation fail\n");
|
pr_info("TPM I2C initialisation fail\n");
|
||||||
return err;
|
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_serirq);
|
||||||
gpio_free(pin_infos->io_lpcpd);
|
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) {
|
if (pin_infos->tpm_i2c_buffer[1] != NULL) {
|
||||||
kzfree(pin_infos->tpm_i2c_buffer[1]);
|
kzfree(pin_infos->tpm_i2c_buffer[1]);
|
||||||
pin_infos->tpm_i2c_buffer[1] = NULL;
|
pin_infos->tpm_i2c_buffer[1] = NULL;
|
||||||
|
|
|
@ -53,7 +53,6 @@ struct st33zp24_platform_data {
|
||||||
int io_serirq;
|
int io_serirq;
|
||||||
int io_lpcpd;
|
int io_lpcpd;
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
bool bChipF;
|
|
||||||
u8 *tpm_i2c_buffer[2]; /* 0 Request 1 Response */
|
u8 *tpm_i2c_buffer[2]; /* 0 Request 1 Response */
|
||||||
struct completion irq_detection;
|
struct completion irq_detection;
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче