lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250923170744.1749132-3-jarkko@kernel.org>
Date: Tue, 23 Sep 2025 20:07:43 +0300
From: Jarkko Sakkinen <jarkko@...nel.org>
To: linux-integrity@...r.kernel.org
Cc: Stefano Garzarella <sgarzare@...hat.com>,
	Jarkko Sakkinen <jarkko.sakkinen@...nsys.com>,
	Peter Huewe <peterhuewe@....de>,
	Jarkko Sakkinen <jarkko@...nel.org>,
	Jason Gunthorpe <jgg@...pe.ca>,
	David Howells <dhowells@...hat.com>,
	Paul Moore <paul@...l-moore.com>,
	James Morris <jmorris@...ei.org>,
	"Serge E. Hallyn" <serge@...lyn.com>,
	linux-kernel@...r.kernel.org (open list),
	keyrings@...r.kernel.org (open list:KEYS/KEYRINGS),
	linux-security-module@...r.kernel.org (open list:SECURITY SUBSYSTEM)
Subject: [PATCH v11 2/3] tpm: Use TPM_MIN_BUF_SIZE in driver commands

From: Jarkko Sakkinen <jarkko.sakkinen@...nsys.com>

Use TPM_BUF_MIN_SIZE and stack allocation in the following commands:

1. tpm1_startup
2. tpm2_shutdown
3. tpm1_get_random
4. tpm2_do_selftest
5. tpm2_probe
6. tpm2_startup
7. tpm2_get_random
8. vtpm_proxy_request_locality

Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@...nsys.com>
---
v11:
- A new patch that squashes previous stack updates. It's in the end of
  day easier review like this. Thus, also the sanity check list in the
  commit message in order to catch up unintended changes if there were
  any.
---
 drivers/char/tpm/tpm.h            |  9 ++---
 drivers/char/tpm/tpm1-cmd.c       | 22 ++++-------
 drivers/char/tpm/tpm2-cmd.c       | 65 ++++++++++++-------------------
 drivers/char/tpm/tpm_vtpm_proxy.c | 12 +++---
 4 files changed, 42 insertions(+), 66 deletions(-)

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 1a4abe54db15..df426e281f88 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -223,11 +223,10 @@ enum tpm2_pt_props {
 	TPM2_PT_AUDIT_COUNTER_1 = TPM2_PT_VAR + 20,
 };
 
-/* 128 bytes is an arbitrary cap. This could be as large as TPM_BUF_MAX_SIZE - 18
- * bytes, but 128 is still a relatively large number of random bytes and
- * anything much bigger causes users of struct tpm_cmd_t to start getting
- * compiler warnings about stack frame size. */
-#define TPM_MAX_RNG_DATA	128
+/*
+ * The parameter is capped to fit to a stack allocated TPM buffer.
+ */
+#define TPM_MAX_RNG_DATA	(TPM_BUF_MIN_SIZE / 2)
 
 extern const struct class tpm_class;
 extern const struct class tpmrm_class;
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index ca3e7f9a105d..fdb55dab80e1 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -323,19 +323,15 @@ unsigned long tpm1_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
  */
 static int tpm1_startup(struct tpm_chip *chip)
 {
+	u8 buf_data[TPM_BUF_MIN_SIZE];
+	struct tpm_buf *buf = (struct tpm_buf *)buf_data;
 	int rc;
 
-	struct tpm_buf *buf __free(kfree) = kzalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
-
-	dev_info(&chip->dev, "starting up the TPM manually\n");
-
-	tpm_buf_init(buf, TPM_BUF_MAX_SIZE);
+	dev_info(&chip->dev, "TPM_Startup\n");
+	tpm_buf_init(buf, TPM_BUF_MIN_SIZE);
 	tpm_buf_reset(buf, TPM_TAG_RQU_COMMAND, TPM_ORD_STARTUP);
 	tpm_buf_append_u16(buf, TPM_ST_CLEAR);
-
-	rc = tpm_transmit_cmd(chip, buf, 0, "attempting to start the TPM");
+	rc = tpm_transmit_cmd(chip, buf, 0, "TPM_Startup");
 	return rc;
 }
 
@@ -530,6 +526,8 @@ struct tpm1_get_random_out {
  */
 int tpm1_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
 {
+	u8 buf_data[TPM_BUF_MIN_SIZE];
+	struct tpm_buf *buf = (struct tpm_buf *)buf_data;
 	struct tpm1_get_random_out *out;
 	u32 num_bytes =  min_t(u32, max, TPM_MAX_RNG_DATA);
 	u32 total = 0;
@@ -537,11 +535,7 @@ int tpm1_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
 	u32 recd;
 	int rc;
 
-	struct tpm_buf *buf __free(kfree) = kzalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
-
-	tpm_buf_init(buf, TPM_BUF_MAX_SIZE);
+	tpm_buf_init(buf, TPM_BUF_MIN_SIZE);
 	do {
 		tpm_buf_reset(buf, TPM_TAG_RQU_COMMAND, TPM_ORD_GET_RANDOM);
 		tpm_buf_append_u32(buf, num_bytes);
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 245c7c952e82..320dc6ae6af2 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -226,6 +226,8 @@ struct tpm2_get_random_out {
  */
 int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
 {
+	u8 buf_data[TPM_BUF_MIN_SIZE];
+	struct tpm_buf *buf = (struct tpm_buf *)buf_data;
 	struct tpm2_get_random_out *out;
 	struct tpm_header *head;
 	u32 recd;
@@ -239,15 +241,11 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
 	if (!num_bytes || max > TPM_MAX_RNG_DATA)
 		return -EINVAL;
 
-	struct tpm_buf *buf __free(kfree) = kzalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
-
 	err = tpm2_start_auth_session(chip);
 	if (err)
 		return err;
 
-	tpm_buf_init(buf, TPM_BUF_MAX_SIZE);
+	tpm_buf_init(buf, TPM_BUF_MIN_SIZE);
 	do {
 		tpm_buf_reset(buf, TPM2_ST_SESSIONS, TPM2_CC_GET_RANDOM);
 		tpm_buf_append_hmac_session_opt(chip, buf, TPM2_SA_ENCRYPT
@@ -382,14 +380,13 @@ EXPORT_SYMBOL_GPL(tpm2_get_tpm_pt);
  */
 void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
 {
-	struct tpm_buf *buf __free(kfree) = kzalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!buf)
-		return;
+	u8 buf_data[TPM_BUF_MIN_SIZE];
+	struct tpm_buf *buf = (struct tpm_buf *)buf_data;
 
-	tpm_buf_init(buf, TPM_BUF_MAX_SIZE);
+	tpm_buf_init(buf, TPM_BUF_MIN_SIZE);
 	tpm_buf_reset(buf, TPM2_ST_NO_SESSIONS, TPM2_CC_SHUTDOWN);
 	tpm_buf_append_u16(buf, shutdown_type);
-	tpm_transmit_cmd(chip, buf, 0, "stopping the TPM");
+	tpm_transmit_cmd(chip, buf, 0, "TPM2_Shutdown");
 }
 
 /**
@@ -407,58 +404,49 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
  */
 static int tpm2_do_selftest(struct tpm_chip *chip)
 {
+	u8 buf_data[TPM_BUF_MIN_SIZE];
+	struct tpm_buf *buf = (struct tpm_buf *)buf_data;
 	int full;
 	int rc;
 
-	struct tpm_buf *buf __free(kfree) = kzalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
-
-	tpm_buf_init(buf, TPM_BUF_MAX_SIZE);
-	tpm_buf_reset(buf, TPM2_ST_NO_SESSIONS, TPM2_CC_SELF_TEST);
+	tpm_buf_init(buf, TPM_BUF_MIN_SIZE);
 	for (full = 0; full < 2; full++) {
 		tpm_buf_reset(buf, TPM2_ST_NO_SESSIONS, TPM2_CC_SELF_TEST);
 		tpm_buf_append_u8(buf, full);
-		rc = tpm_transmit_cmd(chip, buf, 0,
-				      "attempting the self test");
-
+		rc = tpm_transmit_cmd(chip, buf, 0, "TPM2_SelfTest");
 		if (rc == TPM2_RC_TESTING)
 			rc = TPM2_RC_SUCCESS;
 		if (rc == TPM2_RC_INITIALIZE || rc == TPM2_RC_SUCCESS)
 			return rc;
 	}
-
 	return rc;
 }
 
 /**
- * tpm2_probe() - probe for the TPM 2.0 protocol
+ * tpm2_probe() - Probe for the TPM 2.0 protocol
  * @chip:	a &tpm_chip instance
  *
- * Send an idempotent TPM 2.0 command and see whether there is TPM2 chip in the
- * other end based on the response tag. The flag TPM_CHIP_FLAG_TPM2 is set by
- * this function if this is the case.
+ * Sends an idempotent TPM 2.0 command, and based on the response tag deduces
+ * whether a functional TPM2 chip is on the other side. When the result is
+ * positive, TPM_CHIP_FLAG_TPM2 is append to the chip's flags.
  *
  * Return:
- *   0 on success,
- *   -errno otherwise
+ * * 0 on success,
+ * * -errno otherwise
  */
 int tpm2_probe(struct tpm_chip *chip)
 {
+	u8 buf_data[TPM_BUF_MIN_SIZE];
+	struct tpm_buf *buf = (struct tpm_buf *)buf_data;
 	struct tpm_header *out;
 	int rc;
 
-	struct tpm_buf *buf __free(kfree) = kzalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
-
-	tpm_buf_init(buf, TPM_BUF_MAX_SIZE);
+	tpm_buf_init(buf, TPM_BUF_MIN_SIZE);
 	tpm_buf_reset(buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
 	tpm_buf_append_u32(buf, TPM2_CAP_TPM_PROPERTIES);
 	tpm_buf_append_u32(buf, TPM_PT_TOTAL_COMMANDS);
 	tpm_buf_append_u32(buf, 1);
 	rc = tpm_transmit_cmd(chip, buf, 0, NULL);
-	/* We ignore TPM return codes on purpose. */
 	if (rc >=  0) {
 		out = (struct tpm_header *)buf->data;
 		if (be16_to_cpu(out->tag) == TPM2_ST_NO_SESSIONS)
@@ -651,17 +639,14 @@ EXPORT_SYMBOL_GPL(tpm2_get_cc_attrs_tbl);
 
 static int tpm2_startup(struct tpm_chip *chip)
 {
-	struct tpm_buf *buf __free(kfree) = kzalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
+	u8 buf_data[TPM_BUF_MIN_SIZE];
+	struct tpm_buf *buf = (struct tpm_buf *)buf_data;
 
-	dev_info(&chip->dev, "starting up the TPM manually\n");
-
-	tpm_buf_init(buf, TPM_BUF_MAX_SIZE);
+	dev_info(&chip->dev, "TPM2_Startup\n");
+	tpm_buf_init(buf, TPM_BUF_MIN_SIZE);
 	tpm_buf_reset(buf, TPM2_ST_NO_SESSIONS, TPM2_CC_STARTUP);
 	tpm_buf_append_u16(buf, TPM2_SU_CLEAR);
-
-	return tpm_transmit_cmd(chip, buf, 0, "attempting to start the TPM");
+	return tpm_transmit_cmd(chip, buf, 0, "TPM2_Startup");
 }
 
 /**
diff --git a/drivers/char/tpm/tpm_vtpm_proxy.c b/drivers/char/tpm/tpm_vtpm_proxy.c
index e5de14379eb2..0f1b1b67ed4e 100644
--- a/drivers/char/tpm/tpm_vtpm_proxy.c
+++ b/drivers/char/tpm/tpm_vtpm_proxy.c
@@ -395,15 +395,13 @@ static bool vtpm_proxy_tpm_req_canceled(struct tpm_chip  *chip, u8 status)
 
 static int vtpm_proxy_request_locality(struct tpm_chip *chip, int locality)
 {
-	int rc;
-	const struct tpm_header *header;
 	struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
+	u8 buf_data[TPM_BUF_MIN_SIZE];
+	struct tpm_buf *buf = (struct tpm_buf *)buf_data;
+	const struct tpm_header *header;
+	int rc;
 
-	struct tpm_buf *buf __free(kfree) = kzalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
-
-	tpm_buf_init(buf, TPM_BUF_MAX_SIZE);
+	tpm_buf_init(buf, TPM_BUF_MIN_SIZE);
 	if (chip->flags & TPM_CHIP_FLAG_TPM2)
 		tpm_buf_reset(buf, TPM2_ST_SESSIONS, TPM2_CC_SET_LOCALITY);
 	else
-- 
2.39.5


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ