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:
Kent Yoder 2013-01-18 17:42:25 -06:00
Родитель d459335381
Коммит 1fbc5e9535
2 изменённых файлов: 11 добавлений и 6 удалений

Просмотреть файл

@ -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;