diff mbox series

tpm: Define TPM2_SPACE_BUFFER_SIZE to replace the use of PAGE_SIZE

Message ID 20200702225603.293122-1-jarkko.sakkinen@linux.intel.com (mailing list archive)
State Under Review
Headers show
Series tpm: Define TPM2_SPACE_BUFFER_SIZE to replace the use of PAGE_SIZE | expand

Commit Message

Jarkko Sakkinen July 2, 2020, 10:55 p.m. UTC
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.

Reported-by: Stefan Berger <stefanb@linux.ibm.com>
Cc: stable@vger.kernel.org
Fixes: 745b361e989a ("tpm: infrastructure for TPM spaces")
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
v2: Also use the new buffer size for chip->work_buffer (reported by stefanb)
 drivers/char/tpm/tpm-chip.c   |  9 ++-------
 drivers/char/tpm/tpm.h        |  5 ++++-
 drivers/char/tpm/tpm2-space.c | 26 ++++++++++++++++----------
 drivers/char/tpm/tpmrm-dev.c  |  2 +-
 include/linux/tpm.h           |  5 +++--
 5 files changed, 26 insertions(+), 21 deletions(-)

Comments

Jerry Snitselaar July 2, 2020, 11:55 p.m. UTC | #1
On Fri Jul 03 20, Jarkko Sakkinen wrote:
>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.
>
>Reported-by: Stefan Berger <stefanb@linux.ibm.com>
>Cc: stable@vger.kernel.org
>Fixes: 745b361e989a ("tpm: infrastructure for TPM spaces")
>Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>

>---
>v2: Also use the new buffer size for chip->work_buffer (reported by stefanb)
> drivers/char/tpm/tpm-chip.c   |  9 ++-------
> drivers/char/tpm/tpm.h        |  5 ++++-
> drivers/char/tpm/tpm2-space.c | 26 ++++++++++++++++----------
> drivers/char/tpm/tpmrm-dev.c  |  2 +-
> include/linux/tpm.h           |  5 +++--
> 5 files changed, 26 insertions(+), 21 deletions(-)
>
>diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
>index 8c77e88012e9..ddaeceb7e109 100644
>--- a/drivers/char/tpm/tpm-chip.c
>+++ b/drivers/char/tpm/tpm-chip.c
>@@ -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;
> 	}
>diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
>index 0fbcede241ea..947d1db0a5cc 100644
>--- a/drivers/char/tpm/tpm.h
>+++ b/drivers/char/tpm/tpm.h
>@@ -59,6 +59,9 @@ enum tpm_addr {
>
> #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;
>@@ -228,7 +231,7 @@ unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
> int tpm2_probe(struct tpm_chip *chip);
> int tpm2_get_cc_attrs_tbl(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,
>diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
>index 982d341d8837..784b8b3cb903 100644
>--- a/drivers/char/tpm/tpm2-space.c
>+++ b/drivers/char/tpm/tpm2-space.c
>@@ -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:
>diff --git a/drivers/char/tpm/tpmrm-dev.c b/drivers/char/tpm/tpmrm-dev.c
>index 7a0a7051a06f..eef0fb06ea83 100644
>--- a/drivers/char/tpm/tpmrm-dev.c
>+++ b/drivers/char/tpm/tpmrm-dev.c
>@@ -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;
>diff --git a/include/linux/tpm.h b/include/linux/tpm.h
>index 03e9b184411b..d501156fedda 100644
>--- a/include/linux/tpm.h
>+++ b/include/linux/tpm.h
>@@ -93,9 +93,10 @@ enum tpm_duration {
>
> struct tpm_space {
> 	u32 context_tbl[3];
>-	u8 *context_buf;
>+	u8  *context_buf;
> 	u32 session_tbl[3];
>-	u8 *session_buf;
>+	u8  *session_buf;
>+	u32 buf_size;
> };
>
> struct tpm_bios_log {
>-- 
>2.25.1
>
Jarkko Sakkinen July 4, 2020, 3:56 a.m. UTC | #2
On Thu, Jul 02, 2020 at 04:55:44PM -0700, Jerry Snitselaar wrote:
> On Fri Jul 03 20, Jarkko Sakkinen wrote:
> > 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.
> > 
> > Reported-by: Stefan Berger <stefanb@linux.ibm.com>
> > Cc: stable@vger.kernel.org
> > Fixes: 745b361e989a ("tpm: infrastructure for TPM spaces")
> > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> 
> Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>

Thank you.

Now only needs tested-by from Stefan.

/Jarkko
Stefan Berger July 6, 2020, 6:06 p.m. UTC | #3
On 7/3/20 11:56 PM, Jarkko Sakkinen wrote:
> On Thu, Jul 02, 2020 at 04:55:44PM -0700, Jerry Snitselaar wrote:
>> On Fri Jul 03 20, Jarkko Sakkinen wrote:
>>> 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.
>>>
>>> Reported-by: Stefan Berger <stefanb@linux.ibm.com>
>>> Cc: stable@vger.kernel.org
>>> Fixes: 745b361e989a ("tpm: infrastructure for TPM spaces")
>>> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
>> Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
> Thank you.
>
> Now only needs tested-by from Stefan.


Tested-by: Stefan Berger <stefanb@linux.ibm.com>


>
> /Jarkko
Jarkko Sakkinen July 6, 2020, 11:01 p.m. UTC | #4
On Mon, Jul 06, 2020 at 02:06:09PM -0400, Stefan Berger wrote:
> On 7/3/20 11:56 PM, Jarkko Sakkinen wrote:
> > On Thu, Jul 02, 2020 at 04:55:44PM -0700, Jerry Snitselaar wrote:
> > > On Fri Jul 03 20, Jarkko Sakkinen wrote:
> > > > 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.
> > > > 
> > > > Reported-by: Stefan Berger <stefanb@linux.ibm.com>
> > > > Cc: stable@vger.kernel.org
> > > > Fixes: 745b361e989a ("tpm: infrastructure for TPM spaces")
> > > > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> > > Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
> > Thank you.
> > 
> > Now only needs tested-by from Stefan.
> 
> 
> Tested-by: Stefan Berger <stefanb@linux.ibm.com>

Thanks. I'll put this eventually to the v5.9 PR.

/Jarkko
diff mbox series

Patch

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 8c77e88012e9..ddaeceb7e109 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -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;
 	}
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 0fbcede241ea..947d1db0a5cc 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -59,6 +59,9 @@  enum tpm_addr {
 
 #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;
@@ -228,7 +231,7 @@  unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
 int tpm2_probe(struct tpm_chip *chip);
 int tpm2_get_cc_attrs_tbl(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,
diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
index 982d341d8837..784b8b3cb903 100644
--- a/drivers/char/tpm/tpm2-space.c
+++ b/drivers/char/tpm/tpm2-space.c
@@ -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:
diff --git a/drivers/char/tpm/tpmrm-dev.c b/drivers/char/tpm/tpmrm-dev.c
index 7a0a7051a06f..eef0fb06ea83 100644
--- a/drivers/char/tpm/tpmrm-dev.c
+++ b/drivers/char/tpm/tpmrm-dev.c
@@ -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;
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 03e9b184411b..d501156fedda 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -93,9 +93,10 @@  enum tpm_duration {
 
 struct tpm_space {
 	u32 context_tbl[3];
-	u8 *context_buf;
+	u8  *context_buf;
 	u32 session_tbl[3];
-	u8 *session_buf;
+	u8  *session_buf;
+	u32 buf_size;
 };
 
 struct tpm_bios_log {