]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
tpm: Unify the mismatching TPM space buffer sizes
authorJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Thu, 2 Jul 2020 22:55:59 +0000 (01:55 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Aug 2020 06:16:27 +0000 (08:16 +0200)
commit 6c4e79d99e6f42b79040f1a33cd4018f5425030b upstream.

The size of the buffers for storing context's and sessions can vary from
arch to arch as PAGE_SIZE can be anything between 4 kB and 256 kB (the
maximum for PPC64). Define a fixed buffer size set to 16 kB. This should be
enough for most use with three handles (that is how many we allow at the
moment). Parametrize the buffer size while doing this, so that it is easier
to revisit this later on if required.

Cc: stable@vger.kernel.org
Reported-by: Stefan Berger <stefanb@linux.ibm.com>
Fixes: 745b361e989a ("tpm: infrastructure for TPM spaces")
Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/char/tpm/tpm-chip.c
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm2-space.c
drivers/char/tpm/tpmrm-dev.c
include/linux/tpm.h

index 58073836b5555d1f5b540434cb92acb5c3b264e5..1838039b03333dceb9dabfeb6007e7806b67b8ed 100644 (file)
@@ -386,13 +386,8 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
        chip->cdev.owner = THIS_MODULE;
        chip->cdevs.owner = THIS_MODULE;
 
-       chip->work_space.context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
-       if (!chip->work_space.context_buf) {
-               rc = -ENOMEM;
-               goto out;
-       }
-       chip->work_space.session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
-       if (!chip->work_space.session_buf) {
+       rc = tpm2_init_space(&chip->work_space, TPM2_SPACE_BUFFER_SIZE);
+       if (rc) {
                rc = -ENOMEM;
                goto out;
        }
index 218cb496222a57b00a90f9ea4dc739a70ead58ac..37f010421a369d879058f51775b70d13eee48b1a 100644 (file)
@@ -177,6 +177,9 @@ struct tpm_header {
 
 #define TPM_TAG_RQU_COMMAND 193
 
+/* TPM2 specific constants. */
+#define TPM2_SPACE_BUFFER_SIZE         16384 /* 16 kB */
+
 struct stclear_flags_t {
        __be16  tag;
        u8      deactivated;
@@ -456,7 +459,7 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
 unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
 int tpm2_probe(struct tpm_chip *chip);
 int tpm2_find_cc(struct tpm_chip *chip, u32 cc);
-int tpm2_init_space(struct tpm_space *space);
+int tpm2_init_space(struct tpm_space *space, unsigned int buf_size);
 void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space);
 void tpm2_flush_space(struct tpm_chip *chip);
 int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u8 *cmd,
index 982d341d88379aac6330fe2543f4e17650e5e7ee..784b8b3cb903f5e098d1eaac235fec69f5a5a4d6 100644 (file)
@@ -38,18 +38,21 @@ static void tpm2_flush_sessions(struct tpm_chip *chip, struct tpm_space *space)
        }
 }
 
-int tpm2_init_space(struct tpm_space *space)
+int tpm2_init_space(struct tpm_space *space, unsigned int buf_size)
 {
-       space->context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+       space->context_buf = kzalloc(buf_size, GFP_KERNEL);
        if (!space->context_buf)
                return -ENOMEM;
 
-       space->session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+       space->session_buf = kzalloc(buf_size, GFP_KERNEL);
        if (space->session_buf == NULL) {
                kfree(space->context_buf);
+               /* Prevent caller getting a dangling pointer. */
+               space->context_buf = NULL;
                return -ENOMEM;
        }
 
+       space->buf_size = buf_size;
        return 0;
 }
 
@@ -311,8 +314,10 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u8 *cmd,
               sizeof(space->context_tbl));
        memcpy(&chip->work_space.session_tbl, &space->session_tbl,
               sizeof(space->session_tbl));
-       memcpy(chip->work_space.context_buf, space->context_buf, PAGE_SIZE);
-       memcpy(chip->work_space.session_buf, space->session_buf, PAGE_SIZE);
+       memcpy(chip->work_space.context_buf, space->context_buf,
+              space->buf_size);
+       memcpy(chip->work_space.session_buf, space->session_buf,
+              space->buf_size);
 
        rc = tpm2_load_space(chip);
        if (rc) {
@@ -492,7 +497,7 @@ static int tpm2_save_space(struct tpm_chip *chip)
                        continue;
 
                rc = tpm2_save_context(chip, space->context_tbl[i],
-                                      space->context_buf, PAGE_SIZE,
+                                      space->context_buf, space->buf_size,
                                       &offset);
                if (rc == -ENOENT) {
                        space->context_tbl[i] = 0;
@@ -509,9 +514,8 @@ static int tpm2_save_space(struct tpm_chip *chip)
                        continue;
 
                rc = tpm2_save_context(chip, space->session_tbl[i],
-                                      space->session_buf, PAGE_SIZE,
+                                      space->session_buf, space->buf_size,
                                       &offset);
-
                if (rc == -ENOENT) {
                        /* handle error saving session, just forget it */
                        space->session_tbl[i] = 0;
@@ -557,8 +561,10 @@ int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
               sizeof(space->context_tbl));
        memcpy(&space->session_tbl, &chip->work_space.session_tbl,
               sizeof(space->session_tbl));
-       memcpy(space->context_buf, chip->work_space.context_buf, PAGE_SIZE);
-       memcpy(space->session_buf, chip->work_space.session_buf, PAGE_SIZE);
+       memcpy(space->context_buf, chip->work_space.context_buf,
+              space->buf_size);
+       memcpy(space->session_buf, chip->work_space.session_buf,
+              space->buf_size);
 
        return 0;
 out:
index 7a0a7051a06fc867aa35e250d8d36d7cde46968b..eef0fb06ea83223cefd9ce823607f2aad298c5ba 100644 (file)
@@ -21,7 +21,7 @@ static int tpmrm_open(struct inode *inode, struct file *file)
        if (priv == NULL)
                return -ENOMEM;
 
-       rc = tpm2_init_space(&priv->space);
+       rc = tpm2_init_space(&priv->space, TPM2_SPACE_BUFFER_SIZE);
        if (rc) {
                kfree(priv);
                return -ENOMEM;
index 53c0ea9ec9df222b3ec3fab64de475a43cc834e5..77fdc988c610e24364f5a408432244c2061780a1 100644 (file)
@@ -93,6 +93,7 @@ struct tpm_space {
        u8 *context_buf;
        u32 session_tbl[3];
        u8 *session_buf;
+       u32 buf_size;
 };
 
 struct tpm_bios_log {