Commit b3d96260 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'fixes-v4.16-rc4' of...

Merge branch 'fixes-v4.16-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security

Pull tpm fixes from James Morris:
 "Bugfixes for TPM, from Jeremy Boone, via Jarkko Sakkinen"

* 'fixes-v4.16-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
  tpm: fix potential buffer overruns caused by bit glitches on the bus
  tpm: st33zp24: fix potential buffer overruns caused by bit glitches on the bus
  tpm_i2c_infineon: fix potential buffer overruns caused by bit glitches on the bus
  tpm_i2c_nuvoton: fix potential buffer overruns caused by bit glitches on the bus
  tpm_tis: fix potential buffer overruns caused by bit glitches on the bus
parents 6f70eb2b 3be23274
...@@ -457,7 +457,7 @@ static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf, ...@@ -457,7 +457,7 @@ static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf,
size_t count) size_t count)
{ {
int size = 0; int size = 0;
int expected; u32 expected;
if (!chip) if (!chip)
return -EBUSY; return -EBUSY;
...@@ -474,7 +474,7 @@ static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf, ...@@ -474,7 +474,7 @@ static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf,
} }
expected = be32_to_cpu(*(__be32 *)(buf + 2)); expected = be32_to_cpu(*(__be32 *)(buf + 2));
if (expected > count) { if (expected > count || expected < TPM_HEADER_SIZE) {
size = -EIO; size = -EIO;
goto out; goto out;
} }
......
...@@ -1190,6 +1190,10 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max) ...@@ -1190,6 +1190,10 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max)
break; break;
recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len); recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len);
if (recd > num_bytes) {
total = -EFAULT;
break;
}
rlength = be32_to_cpu(tpm_cmd.header.out.length); rlength = be32_to_cpu(tpm_cmd.header.out.length);
if (rlength < offsetof(struct tpm_getrandom_out, rng_data) + if (rlength < offsetof(struct tpm_getrandom_out, rng_data) +
......
...@@ -683,6 +683,10 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, ...@@ -683,6 +683,10 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
if (!rc) { if (!rc) {
data_len = be16_to_cpup( data_len = be16_to_cpup(
(__be16 *) &buf.data[TPM_HEADER_SIZE + 4]); (__be16 *) &buf.data[TPM_HEADER_SIZE + 4]);
if (data_len < MIN_KEY_SIZE || data_len > MAX_KEY_SIZE + 1) {
rc = -EFAULT;
goto out;
}
rlength = be32_to_cpu(((struct tpm2_cmd *)&buf) rlength = be32_to_cpu(((struct tpm2_cmd *)&buf)
->header.out.length); ->header.out.length);
......
...@@ -473,7 +473,8 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) ...@@ -473,7 +473,8 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count) static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
{ {
int size = 0; int size = 0;
int expected, status; int status;
u32 expected;
if (count < TPM_HEADER_SIZE) { if (count < TPM_HEADER_SIZE) {
size = -EIO; size = -EIO;
...@@ -488,7 +489,7 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count) ...@@ -488,7 +489,7 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
} }
expected = be32_to_cpu(*(__be32 *)(buf + 2)); expected = be32_to_cpu(*(__be32 *)(buf + 2));
if ((size_t) expected > count) { if (((size_t) expected > count) || (expected < TPM_HEADER_SIZE)) {
size = -EIO; size = -EIO;
goto out; goto out;
} }
......
...@@ -281,7 +281,11 @@ static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count) ...@@ -281,7 +281,11 @@ static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count)
struct device *dev = chip->dev.parent; struct device *dev = chip->dev.parent;
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
s32 rc; s32 rc;
int expected, status, burst_count, retries, size = 0; int status;
int burst_count;
int retries;
int size = 0;
u32 expected;
if (count < TPM_HEADER_SIZE) { if (count < TPM_HEADER_SIZE) {
i2c_nuvoton_ready(chip); /* return to idle */ i2c_nuvoton_ready(chip); /* return to idle */
...@@ -323,7 +327,7 @@ static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count) ...@@ -323,7 +327,7 @@ static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count)
* to machine native * to machine native
*/ */
expected = be32_to_cpu(*(__be32 *) (buf + 2)); expected = be32_to_cpu(*(__be32 *) (buf + 2));
if (expected > count) { if (expected > count || expected < size) {
dev_err(dev, "%s() expected > count\n", __func__); dev_err(dev, "%s() expected > count\n", __func__);
size = -EIO; size = -EIO;
continue; continue;
......
...@@ -270,7 +270,8 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) ...@@ -270,7 +270,8 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
{ {
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
int size = 0; int size = 0;
int expected, status; int status;
u32 expected;
if (count < TPM_HEADER_SIZE) { if (count < TPM_HEADER_SIZE) {
size = -EIO; size = -EIO;
...@@ -285,7 +286,7 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) ...@@ -285,7 +286,7 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
} }
expected = be32_to_cpu(*(__be32 *) (buf + 2)); expected = be32_to_cpu(*(__be32 *) (buf + 2));
if (expected > count) { if (expected > count || expected < TPM_HEADER_SIZE) {
size = -EIO; size = -EIO;
goto out; goto out;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment