Skip to contentSkip to conversation

tpm_tis: Check return values from get_burstcount.

PATCH Superseded Josh Zimmerman 2 participants 3 messages Oct 27, 2016 2 messages not in the archive TPM device driver

v4 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

PATCH v4 1/1 tpm_tis: Check return values from get_burstcount.

If the TPM we're connecting to uses a static burst count, it will report a burst count of zero throughout the response read. However, get_burstcount assumes that a response of zero indicates that the TPM is not ready to receive more data. In this case, it returns a negative error code, which is passed on to tpm_tis_{write,read}_bytes as a u16, causing them to read/write far too many bytes.

This patch checks for negative return codes and bails out from recv_data and tpm_tis_send_data.

Fixes 1107d065fdf1 (tpm_tis: Introduce intermediate layer for TPM access)

---
Changelog v4:
- Add short description to Fixes tag line.
- Remove some unnecessary information in dev_err statements.
Changelog v3:
- Add signed-off-by.
Changelog v2:
- Fix typo (rc->burstcnt)

---
 drivers/char/tpm/tpm_tis_core.c | 9 +++++++++
 1 file changed, 9 insertions(+)
drivers/char/tpm/tpm_tis_core.c +9 -0
index e3bf31b..0f2c233 100644
@@ -186,6 +186,10 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
 				 chip->timeout_c,
 				 &priv->read_queue, true) == 0) {
 		burstcnt = min_t(int, get_burstcount(chip), count - size);
+		if (burstcnt < 0) {
+			dev_err(&chip->dev, "Unable to read burstcount\n");
+			return burstcnt;
+		}
 
 		rc = tpm_tis_read_bytes(priv, TPM_DATA_FIFO(priv->locality),
 					burstcnt, buf + size);
@@ -272,6 +276,11 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
 
 	while (count < len - 1) {
 		burstcnt = min_t(int, get_burstcount(chip), len - count - 1);
+		if (burstcnt < 0) {
+			dev_err(&chip->dev, "Unable to read burstcount\n");
+			rc = burstcnt;
+			goto out_err;
+		}
 		rc = tpm_tis_write_bytes(priv, TPM_DATA_FIFO(priv->locality),
 					 burstcnt, buf + count);
 		if (rc < 0)
Signature · 9 lines
2.8.0.rc3.226.g39d4020


------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive. 
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik

A message that is not in the archive (sent off-list or not yet received): [email protected]

#2 lore raw
Quoted 32 lines

If the TPM we're connecting to uses a static burst count, it will report a burst count of zero throughout the response read. However, get_burstcount assumes that a response of zero indicates that the TPM is not ready to receive more data. In this case, it returns a negative error code, which is passed on to tpm_tis_{write,read}_bytes as a u16, causing them to read/write far too many bytes.

This patch checks for negative return codes and bails out from recv_data and tpm_tis_send_data.

Fixes 1107d065fdf1 (tpm_tis: Introduce intermediate layer for TPM access)

---
Changelog v4:
- Add short description to Fixes tag line.
- Remove some unnecessary information in dev_err statements.
Changelog v3:
- Add signed-off-by.
Changelog v2:
- Fix typo (rc->burstcnt)

---
 drivers/char/tpm/tpm_tis_core.c | 9 +++++++++
 1 file changed, 9 insertions(+)
drivers/char/tpm/tpm_tis_core.c +0 -0
index e3bf31b..0f2c233 100644

drivers/char/tpm/tpm_tis_core.c static int recv_data(struct tpm_chip *chip, u8 *buf, · line 190

Quoted 5 lines
drivers/char/tpm/tpm_tis_core.c +1 -0
@@ -186,6 +186,10 @@ static int recv_data(struct tpm_chip *chip, u8 *buf,
 size_t count)
 				 chip->timeout_c,
 				 &priv->read_queue, true) == 0) {
 		burstcnt = min_t(int, get_burstcount(chip), count - size);
+		if (burstcnt < 0) {

It is much more readable to directly check get_burstcount return value, 'count - size' is protected be above condition to not reach negative value.
burstcnt = get_burstcount(chip)
if (brustcnt < 0) ...

drivers/char/tpm/tpm_tis_core.c static int tpm_tis_send_data(struct tpm_chip *chip, u8 · line 280

Quoted 12 lines
drivers/char/tpm/tpm_tis_core.c +3 -0
+			dev_err(&chip->dev, "Unable to read burstcount\n");
+			return burstcnt;
+		}
 
 		rc = tpm_tis_read_bytes(priv, TPM_DATA_FIFO(priv->locality),
drivers/char/tpm/tpm_tis_core.c +1 -0
 					burstcnt, buf + size);
@@ -272,6 +276,11 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8
 *buf, size_t len)
 
 	while (count < len - 1) {
 		burstcnt = min_t(int, get_burstcount(chip), len - count - 1);
+		if (burstcnt < 0) {

Same here

Quoted 9 lines
drivers/char/tpm/tpm_tis_core.c +4 -0
+			dev_err(&chip->dev, "Unable to read burstcount\n");
+			rc = burstcnt;
+			goto out_err;
+		}
 		rc = tpm_tis_write_bytes(priv, TPM_DATA_FIFO(priv->locality),
 					 burstcnt, buf + count);

if (rc < 0)
--
2.8.0.rc3.226.g39d4020

Thanks
Tomas

------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers Did the resurgence of CLI tooling catch you by surprise? Reconnect with the command line and become more productive. Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik

A message that is not in the archive (sent off-list or not yet received): 5B8DA87D05A7694D9FA63FD143655C1B5430F484-Jy8z56yoSI8MvF1YICWikbfspsVTdybXVpNB7YpNyf8@public.gmane.org

#4 lore raw

Thanks, that's a fair point. Updated patch sent.

Josh

Quoted 73 lines · Tomas
Quoted 2 lines

If the TPM we're connecting to uses a static burst count, it will report

a burst

Quoted 1 line

count of zero throughout the response read. However, get_burstcount

assumes

Quoted 1 line

that a response of zero indicates that the TPM is not ready to receive

more

Quoted 1 line

data. In this case, it returns a negative error code, which is passed on

to

Quoted 1 line

tpm_tis_{write,read}_bytes as a u16, causing them to read/write far too

many

Quoted 3 lines

bytes.

This patch checks for negative return codes and bails out from recv_data

and

Quoted 3 lines

tpm_tis_send_data.

Fixes 1107d065fdf1 (tpm_tis: Introduce intermediate layer for TPM

access)

drivers/char/tpm/tpm_tis_

Quoted 16 lines

---
Changelog v4:
- Add short description to Fixes tag line.
- Remove some unnecessary information in dev_err statements.
Changelog v3:
- Add signed-off-by.
Changelog v2:
- Fix typo (rc->burstcnt)

---
 drivers/char/tpm/tpm_tis_core.c | 9 +++++++++
 1 file changed, 9 insertions(+)
drivers/char/tpm/tpm_tis_ renamed from drivers/char/tpm/tpm_tis_core.c +0 -0

core.c

drivers/char/tpm/tpm_tis_core.c static int recv_data(struct tpm_chip *chip, u8 *buf, · line 190

Quoted 9 lines

index e3bf31b..0f2c233 100644

drivers/char/tpm/tpm_tis_core.c +1 -0
@@ -186,6 +186,10 @@ static int recv_data(struct tpm_chip *chip, u8 *buf,
 size_t count)
                               chip->timeout_c,
                               &priv->read_queue, true) == 0) {
              burstcnt = min_t(int, get_burstcount(chip), count - size);
+             if (burstcnt < 0) {

It is much more readable to directly check get_burstcount return value, 'count - size' is protected be above condition to not reach negative value.
burstcnt = get_burstcount(chip)
if (brustcnt < 0) ...

drivers/char/tpm/tpm_tis_core.c static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)

Quoted 5 lines
drivers/char/tpm/tpm_tis_core.c +3 -0
+                     dev_err(&chip->dev, "Unable to read burstcount\n");
+                     return burstcnt;
+             }
 
              rc = tpm_tis_read_bytes(priv,

TPM_DATA_FIFO(priv->locality),

drivers/char/tpm/tpm_tis_core.c static int tpm_tis_send_data(struct tpm_chip *chip,

Quoted 2 lines
                                      burstcnt, buf + size);
drivers/char/tpm/tpm_tis_core.c +0 -0
@@ -272,6 +276,11 @@ static int tpm_tis_send_data(struct tpm_chip *chip,

u8

drivers/char/tpm/tpm_tis_core.c static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)

Quoted 4 lines
drivers/char/tpm/tpm_tis_core.c +0 -0
 *buf, size_t len)
 
      while (count < len - 1) {
              burstcnt = min_t(int, get_burstcount(chip), len - count -

1);

drivers/char/tpm/tpm_tis_core.c static int tpm_tis_send_data(struct tpm_chip *chip, · line 280

Quoted 1 line
drivers/char/tpm/tpm_tis_core.c +1 -0
+             if (burstcnt < 0) {

Same here

drivers/char/tpm/tpm_tis_core.c static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)

Quoted 5 lines
drivers/char/tpm/tpm_tis_core.c +4 -0
+                     dev_err(&chip->dev, "Unable to read burstcount\n");
+                     rc = burstcnt;
+                     goto out_err;
+             }
              rc = tpm_tis_write_bytes(priv,
Quoted 9 lines

TPM_DATA_FIFO(priv->locality),

Quoted 4 lines
drivers/char/tpm/tpm_tis_core.c +0 -0
                                       burstcnt, buf + count);
              if (rc < 0)

--
2.8.0.rc3.226.g39d4020

Thanks
Tomas

------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers Did the resurgence of CLI tooling catch you by surprise? Reconnect with the command line and become more productive. Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik

_______________________________________________
tpmdd-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel