diff options
author | Kent Yoder <key@linux.vnet.ibm.com> | 2013-01-18 18:42:25 -0500 |
---|---|---|
committer | Kent Yoder <key@linux.vnet.ibm.com> | 2013-02-05 10:38:24 -0500 |
commit | 1fbc5e95356a4600fab3a04a82dc8bb49591aedd (patch) | |
tree | dd1a2e3d7370d592c58fdee2e983d2f80412bb07 /drivers/char/tpm | |
parent | d459335381eca1cb91fefb87021d3d172342e55a (diff) |
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>
Diffstat (limited to 'drivers/char/tpm')
-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) | |||
658 | err = 0; | 658 | err = 0; |
659 | 659 | ||
660 | if (client == NULL) { | 660 | if (client == NULL) { |
661 | dev_info(&client->dev, "client is NULL. exiting.\n"); | 661 | pr_info("%s: i2c client is NULL. Device not accessible.\n", |
662 | __func__); | ||
662 | err = -ENODEV; | 663 | err = -ENODEV; |
663 | goto end; | 664 | goto end; |
664 | } | 665 | } |
@@ -677,6 +678,13 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
677 | } | 678 | } |
678 | 679 | ||
679 | platform_data = client->dev.platform_data; | 680 | platform_data = client->dev.platform_data; |
681 | |||
682 | if (!platform_data) { | ||
683 | dev_info(&client->dev, "chip not available\n"); | ||
684 | err = -ENODEV; | ||
685 | goto _tpm_clean_answer; | ||
686 | } | ||
687 | |||
680 | platform_data->tpm_i2c_buffer[0] = | 688 | platform_data->tpm_i2c_buffer[0] = |
681 | kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); | 689 | kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); |
682 | if (platform_data->tpm_i2c_buffer[0] == NULL) { | 690 | 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) | |||
759 | tpm_get_timeouts(chip); | 767 | tpm_get_timeouts(chip); |
760 | 768 | ||
761 | i2c_set_clientdata(client, chip); | 769 | i2c_set_clientdata(client, chip); |
762 | platform_data->bChipF = false; | ||
763 | 770 | ||
764 | dev_info(chip->dev, "TPM I2C Initialized\n"); | 771 | dev_info(chip->dev, "TPM I2C Initialized\n"); |
765 | return 0; | 772 | return 0; |
@@ -779,7 +786,6 @@ _tpm_clean_response1: | |||
779 | platform_data->tpm_i2c_buffer[0] = NULL; | 786 | platform_data->tpm_i2c_buffer[0] = NULL; |
780 | _tpm_clean_answer: | 787 | _tpm_clean_answer: |
781 | tpm_remove_hardware(chip->dev); | 788 | tpm_remove_hardware(chip->dev); |
782 | platform_data->bChipF = true; | ||
783 | end: | 789 | end: |
784 | pr_info("TPM I2C initialisation fail\n"); | 790 | pr_info("TPM I2C initialisation fail\n"); |
785 | return err; | 791 | return err; |
@@ -803,8 +809,8 @@ static __devexit int tpm_st33_i2c_remove(struct i2c_client *client) | |||
803 | gpio_free(pin_infos->io_serirq); | 809 | gpio_free(pin_infos->io_serirq); |
804 | gpio_free(pin_infos->io_lpcpd); | 810 | gpio_free(pin_infos->io_lpcpd); |
805 | 811 | ||
806 | if (pin_infos->bChipF != true) | 812 | tpm_remove_hardware(chip->dev); |
807 | tpm_remove_hardware(chip->dev); | 813 | |
808 | if (pin_infos->tpm_i2c_buffer[1] != NULL) { | 814 | if (pin_infos->tpm_i2c_buffer[1] != NULL) { |
809 | kzfree(pin_infos->tpm_i2c_buffer[1]); | 815 | kzfree(pin_infos->tpm_i2c_buffer[1]); |
810 | pin_infos->tpm_i2c_buffer[1] = NULL; | 816 | 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 { | |||
53 | int io_serirq; | 53 | int io_serirq; |
54 | int io_lpcpd; | 54 | int io_lpcpd; |
55 | struct i2c_client *client; | 55 | struct i2c_client *client; |
56 | bool bChipF; | ||
57 | u8 *tpm_i2c_buffer[2]; /* 0 Request 1 Response */ | 56 | u8 *tpm_i2c_buffer[2]; /* 0 Request 1 Response */ |
58 | struct completion irq_detection; | 57 | struct completion irq_detection; |
59 | struct mutex lock; | 58 | struct mutex lock; |