Once cdev_add is done the device node is visible to user space and
could have been opened. Thus we have to go through the locking
process in tpm_del_char_device if device_add fails.
Fixes: 2c91ce8523a ("tpm: fix the rollback in tpm_chip_register()")
Signed-off-by: Jason Gunthorpe <[email protected]>
---
drivers/char/tpm/tpm-chip.c | 43 ++++++++++++++++++++++---------------------
1 file changed, 22 insertions(+), 21 deletions(-)
static function moved to avoid a prototype
This was noticed while reviewing the cdev patchset from Logan
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index a77262d31911a1..c82acf0a6e7353 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -226,6 +226,26 @@ struct tpm_chip *tpmm_chip_alloc(struct device *pdev,
}
EXPORT_SYMBOL_GPL(tpmm_chip_alloc);
+static void tpm_del_char_device(struct tpm_chip *chip, bool with_device)
+{
+ cdev_del(&chip->cdev);
+ if (with_device) {
+ device_del(&chip->dev);
+
+ /* Make the chip unavailable. */
+ mutex_lock(&idr_lock);
+ idr_replace(&dev_nums_idr, NULL, chip->dev_num);
+ mutex_unlock(&idr_lock);
+ }
+
+ /* Make the driver uncallable. */
+ down_write(&chip->ops_sem);
+ if (chip->flags & TPM_CHIP_FLAG_TPM2)
+ tpm2_shutdown(chip, TPM2_SU_CLEAR);
+ chip->ops = NULL;
+ up_write(&chip->ops_sem);
+}
+
static int tpm_add_char_device(struct tpm_chip *chip)
{
int rc;
@@ -246,8 +266,7 @@ static int tpm_add_char_device(struct tpm_chip *chip)
"unable to device_register() %s, major %d, minor %d,
err=%d\n",
dev_name(&chip->dev), MAJOR(chip->dev.devt),
MINOR(chip->dev.devt), rc);
-
- cdev_del(&chip->cdev);
+ tpm_del_char_device(chip, false);
return rc;
}
@@ -259,24 +278,6 @@ static int tpm_add_char_device(struct tpm_chip *chip)
return rc;
}
-static void tpm_del_char_device(struct tpm_chip *chip)
-{
- cdev_del(&chip->cdev);
- device_del(&chip->dev);
-
- /* Make the chip unavailable. */
- mutex_lock(&idr_lock);
- idr_replace(&dev_nums_idr, NULL, chip->dev_num);
- mutex_unlock(&idr_lock);
-
- /* Make the driver uncallable. */
- down_write(&chip->ops_sem);
- if (chip->flags & TPM_CHIP_FLAG_TPM2)
- tpm2_shutdown(chip, TPM2_SU_CLEAR);
- chip->ops = NULL;
- up_write(&chip->ops_sem);
-}
-
static void tpm_del_legacy_sysfs(struct tpm_chip *chip)
{
struct attribute **i;
@@ -384,6 +385,6 @@ void tpm_chip_unregister(struct tpm_chip *chip)
{
tpm_del_legacy_sysfs(chip);
tpm_bios_log_teardown(chip);
- tpm_del_char_device(chip);
+ tpm_del_char_device(chip, true);
}
EXPORT_SYMBOL_GPL(tpm_chip_unregister);
--
2.7.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
tpmdd-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel