[U-Boot] [PATCH 0/3] Fix potential buffer overruns in TPM driver

From: Jeremy Boone jeremy.boone@nccgroup.trust
The TPM response packet often contains a variable-length payload. It is the responsibility of U-Boot driver code to ensure that the length value that has been extracted from the response packet's header or body is appropriately sized before copying that data into another buffer.
Jeremy Boone (3): STMicro TPM: Fix potential buffer overruns Infineon TPM: Fix potential buffer overruns Atmel TPM: Fix potential buffer overruns
drivers/tpm/tpm_atmel_twi.c | 14 ++++++++++++-- drivers/tpm/tpm_tis_infineon.c | 5 +++-- drivers/tpm/tpm_tis_st33zp24_i2c.c | 5 +++-- drivers/tpm/tpm_tis_st33zp24_spi.c | 5 +++-- 4 files changed, 21 insertions(+), 8 deletions(-)

From: Jeremy Boone jeremy.boone@nccgroup.trust
This patch prevents integer underflow when the length was too small, which could lead to memory corruption.
Signed-off-by: Jeremy Boone jeremy.boone@nccgroup.trust --- drivers/tpm/tpm_tis_st33zp24_i2c.c | 5 +++-- drivers/tpm/tpm_tis_st33zp24_spi.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/tpm/tpm_tis_st33zp24_i2c.c b/drivers/tpm/tpm_tis_st33zp24_i2c.c index c8d0125..245218f 100644 --- a/drivers/tpm/tpm_tis_st33zp24_i2c.c +++ b/drivers/tpm/tpm_tis_st33zp24_i2c.c @@ -303,7 +303,8 @@ static int st33zp24_i2c_recv_data(struct udevice *dev, u8 *buf, size_t count) static int st33zp24_i2c_recv(struct udevice *dev, u8 *buf, size_t count) { struct tpm_chip *chip = dev_get_priv(dev); - int size, expected; + int size; + unsigned int expected;
if (!chip) return -ENODEV; @@ -320,7 +321,7 @@ static int st33zp24_i2c_recv(struct udevice *dev, u8 *buf, size_t count) }
expected = get_unaligned_be32(buf + 2); - if (expected > count) { + if (expected > count || expected < TPM_HEADER_SIZE) { size = -EIO; goto out; } diff --git a/drivers/tpm/tpm_tis_st33zp24_spi.c b/drivers/tpm/tpm_tis_st33zp24_spi.c index dcf55ee..c4c5e05 100644 --- a/drivers/tpm/tpm_tis_st33zp24_spi.c +++ b/drivers/tpm/tpm_tis_st33zp24_spi.c @@ -431,7 +431,8 @@ static int st33zp24_spi_recv_data(struct udevice *dev, u8 *buf, size_t count) static int st33zp24_spi_recv(struct udevice *dev, u8 *buf, size_t count) { struct tpm_chip *chip = dev_get_priv(dev); - int size, expected; + int size; + unsigned int expected;
if (!chip) return -ENODEV; @@ -448,7 +449,7 @@ static int st33zp24_spi_recv(struct udevice *dev, u8 *buf, size_t count) }
expected = get_unaligned_be32(buf + 2); - if (expected > count) { + if (expected > count || expected < TPM_HEADER_SIZE) { size = -EIO; goto out; }

On Mon, Feb 12, 2018 at 05:56:35PM -0500, Jeremy Boone wrote:
From: Jeremy Boone jeremy.boone@nccgroup.trust
This patch prevents integer underflow when the length was too small, which could lead to memory corruption.
Signed-off-by: Jeremy Boone jeremy.boone@nccgroup.trust
Applied to u-boot/master, thanks!

From: Jeremy Boone jeremy.boone@nccgroup.trust
Ensure that the Infineon I2C and SPI TPM driver performs adequate validation of the length extracted from the TPM response header. This patch prevents integer underflow when the length was too small, which could lead to memory corruption.
Signed-off-by: Jeremy Boone jeremy.boone@nccgroup.trust --- drivers/tpm/tpm_tis_infineon.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/tpm/tpm_tis_infineon.c b/drivers/tpm/tpm_tis_infineon.c index e3e20d8..41b748e 100644 --- a/drivers/tpm/tpm_tis_infineon.c +++ b/drivers/tpm/tpm_tis_infineon.c @@ -374,7 +374,8 @@ static int tpm_tis_i2c_recv(struct udevice *dev, u8 *buf, size_t count) { struct tpm_chip *chip = dev_get_priv(dev); int size = 0; - int expected, status; + int status; + unsigned int expected; int rc;
status = tpm_tis_i2c_status(dev); @@ -394,7 +395,7 @@ static int tpm_tis_i2c_recv(struct udevice *dev, u8 *buf, size_t count) }
expected = get_unaligned_be32(buf + TPM_RSP_SIZE_BYTE); - if ((size_t)expected > count) { + if ((size_t)expected > count || (size_t)expected < TPM_HEADER_SIZE) { debug("Error size=%x, expected=%x, count=%x\n", size, expected, count); return -ENOSPC;

On Mon, Feb 12, 2018 at 05:56:36PM -0500, Jeremy Boone wrote:
From: Jeremy Boone jeremy.boone@nccgroup.trust
Ensure that the Infineon I2C and SPI TPM driver performs adequate validation of the length extracted from the TPM response header. This patch prevents integer underflow when the length was too small, which could lead to memory corruption.
Signed-off-by: Jeremy Boone jeremy.boone@nccgroup.trust
Applied to u-boot/master, thanks!

From: Jeremy Boone jeremy.boone@nccgroup.trust
Ensure that the Atmel TPM driver performs sufficient validation of the length returned in the TPM response header. This patch prevents memory corruption if the header contains a length value that is larger than the destination buffer.
Signed-off-by: Jeremy Boone jeremy.boone@nccgroup.trust --- drivers/tpm/tpm_atmel_twi.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/tpm/tpm_atmel_twi.c b/drivers/tpm/tpm_atmel_twi.c index eba654b..4fd772d 100644 --- a/drivers/tpm/tpm_atmel_twi.c +++ b/drivers/tpm/tpm_atmel_twi.c @@ -106,13 +106,23 @@ static int tpm_atmel_twi_xfer(struct udevice *dev, udelay(100); } if (!res) { - *recv_len = get_unaligned_be32(recvbuf + 2); - if (*recv_len > 10) + unsigned int hdr_recv_len; + hdr_recv_len = get_unaligned_be32(recvbuf + 2); + if (hdr_recv_len < 10) { + puts("tpm response header too small\n"); + return -1; + } else if (hdr_recv_len > *recv_len) { + puts("tpm response length is bigger than receive buffer\n"); + return -1; + } else { + *recv_len = hdr_recv_len; #ifndef CONFIG_DM_I2C res = i2c_read(0x29, 0, 0, recvbuf, *recv_len); #else res = dm_i2c_read(dev, 0, recvbuf, *recv_len); #endif + + } } if (res) { printf("i2c_read returned %d (rlen=%d)\n", res, *recv_len);

On Mon, Feb 12, 2018 at 05:56:37PM -0500, Jeremy Boone wrote:
From: Jeremy Boone jeremy.boone@nccgroup.trust
Ensure that the Atmel TPM driver performs sufficient validation of the length returned in the TPM response header. This patch prevents memory corruption if the header contains a length value that is larger than the destination buffer.
Signed-off-by: Jeremy Boone jeremy.boone@nccgroup.trust
Applied to u-boot/master, thanks!
participants (2)
-
Jeremy Boone
-
Tom Rini