summaryrefslogtreecommitdiff
path: root/drivers/char/tpm/tpm-chip.c
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2017-01-31 15:47:31 -0800
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2017-04-03 22:46:02 +0300
commit4d57856a21ed2abe33412e0526cc84bdcf67ea08 (patch)
tree69d2ef5b2dfab9ea14b68f7efdb8e90503cfba57 /drivers/char/tpm/tpm-chip.c
parentfdc915f7f71939ad5a3dda3389b8d2d7a7c5ee66 (diff)
tpm2: add session handle context saving and restoring to the space code
Sessions are different from transient objects in that their handles may not be virtualized (because they're used for some hmac calculations). Additionally when a session is context saved, a vestigial memory remains in the TPM and if it is also flushed, that will be lost and the session context will refuse to load next time, so the code is updated to flush only transient objects after a context save. Add a separate array (chip->session_tbl) to save and restore sessions by handle. Use the failure of a context save or load to signal that the session has been flushed from the TPM and we can remove its memory from chip->session_tbl. Sessions are also isolated during each instance of a tpm space. This means that spaces shouldn't be able to see each other's sessions and is enforced by ensuring that a space user may only refer to sessions handles that are present in their own chip->session_tbl. Finally when a space is closed, all the sessions belonging to it should be flushed so the handles may be re-used by other spaces. Note that if we get a session save or load error, all sessions are effectively flushed. Even though we restore the session buffer, all the old sessions will refuse to load after the flush and they'll be purged from our session memory. This means that while transient context handling is still soft in the face of errors, session handling is hard (any failure of the model means all sessions are lost). Fixes-from: Colin Ian King <colin.king@canonical.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Diffstat (limited to 'drivers/char/tpm/tpm-chip.c')
-rw-r--r--drivers/char/tpm/tpm-chip.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 187ec04ce9c3..aade6995f310 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -130,6 +130,7 @@ static void tpm_dev_release(struct device *dev)
kfree(chip->log.bios_event_log);
kfree(chip->work_space.context_buf);
+ kfree(chip->work_space.session_buf);
kfree(chip);
}
@@ -224,6 +225,11 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
rc = -ENOMEM;
goto out;
}
+ chip->work_space.session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!chip->work_space.session_buf) {
+ rc = -ENOMEM;
+ goto out;
+ }
return chip;
@@ -294,7 +300,6 @@ static int tpm_add_char_device(struct tpm_chip *chip)
"unable to cdev_add() %s, major %d, minor %d, err=%d\n",
dev_name(&chip->devs), MAJOR(chip->devs.devt),
MINOR(chip->devs.devt), rc);
- tpm_del_char_device(chip, true);
return rc;
}
@@ -306,7 +311,6 @@ static int tpm_add_char_device(struct tpm_chip *chip)
dev_name(&chip->devs), MAJOR(chip->devs.devt),
MINOR(chip->devs.devt), rc);
cdev_del(&chip->cdevs);
- tpm_del_char_device(chip, true);
return rc;
}