From: Sasha Levin (Microsoft) Date: Wed, 17 Apr 2019 17:16:23 +0000 (-0400) Subject: patches for 4.9 X-Git-Tag: v4.9.170~22 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fkernel%2Fstable-queue.git;a=commitdiff_plain;h=1aa0fa4fcee40237e1ca2f483a55f52c8a49d8e8 patches for 4.9 Signed-off-by: Sasha Levin (Microsoft) --- diff --git a/queue-4.9/series b/queue-4.9/series index ed54a65307..a9c733da4d 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -45,3 +45,4 @@ arm-8839-1-kprobe-make-patch_lock-a-raw_spinlock_t.patch appletalk-fix-use-after-free-in-atalk_proc_exit.patch lib-div64.c-off-by-one-in-shift.patch include-linux-swap.h-use-offsetof-instead-of-custom-.patch +tpm-tpm_crb-avoid-unaligned-reads-in-crb_recv.patch diff --git a/queue-4.9/tpm-tpm_crb-avoid-unaligned-reads-in-crb_recv.patch b/queue-4.9/tpm-tpm_crb-avoid-unaligned-reads-in-crb_recv.patch new file mode 100644 index 0000000000..141acca889 --- /dev/null +++ b/queue-4.9/tpm-tpm_crb-avoid-unaligned-reads-in-crb_recv.patch @@ -0,0 +1,77 @@ +From 7dd49a1da166df1e0620aef1f17050de166a7d07 Mon Sep 17 00:00:00 2001 +From: Jarkko Sakkinen +Date: Wed, 17 Apr 2019 17:59:15 +0300 +Subject: tpm/tpm_crb: Avoid unaligned reads in crb_recv() + +commit 3d7a850fdc1a2e4d2adbc95cc0fc962974725e88 upstream + +The current approach to read first 6 bytes from the response and then tail +of the response, can cause the 2nd memcpy_fromio() to do an unaligned read +(e.g. read 32-bit word from address aligned to a 16-bits), depending on how +memcpy_fromio() is implemented. If this happens, the read will fail and the +memory controller will fill the read with 1's. + +This was triggered by 170d13ca3a2f, which should be probably refined to +check and react to the address alignment. Before that commit, on x86 +memcpy_fromio() turned out to be memcpy(). By a luck GCC has done the right +thing (from tpm_crb's perspective) for us so far, but we should not rely on +that. Thus, it makes sense to fix this also in tpm_crb, not least because +the fix can be then backported to stable kernels and make them more robust +when compiled in differing environments. + +Cc: stable@vger.kernel.org +Cc: James Morris +Cc: Tomas Winkler +Cc: Jerry Snitselaar +Fixes: 30fc8d138e91 ("tpm: TPM 2.0 CRB Interface") +Signed-off-by: Jarkko Sakkinen +Reviewed-by: Jerry Snitselaar +Acked-by: Tomas Winkler +Signed-off-by: Sasha Levin (Microsoft) +--- + drivers/char/tpm/tpm_crb.c | 22 ++++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c +index fa0f66809503..d29f78441cdb 100644 +--- a/drivers/char/tpm/tpm_crb.c ++++ b/drivers/char/tpm/tpm_crb.c +@@ -102,19 +102,29 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count) + struct crb_priv *priv = dev_get_drvdata(&chip->dev); + unsigned int expected; + +- /* sanity check */ +- if (count < 6) ++ /* A sanity check that the upper layer wants to get at least the header ++ * as that is the minimum size for any TPM response. ++ */ ++ if (count < TPM_HEADER_SIZE) + return -EIO; + ++ /* If this bit is set, according to the spec, the TPM is in ++ * unrecoverable condition. ++ */ + if (ioread32(&priv->cca->sts) & CRB_CTRL_STS_ERROR) + return -EIO; + +- memcpy_fromio(buf, priv->rsp, 6); +- expected = be32_to_cpup((__be32 *) &buf[2]); +- if (expected > count || expected < 6) ++ /* Read the first 8 bytes in order to get the length of the response. ++ * We read exactly a quad word in order to make sure that the remaining ++ * reads will be aligned. ++ */ ++ memcpy_fromio(buf, priv->rsp, 8); ++ ++ expected = be32_to_cpup((__be32 *)&buf[2]); ++ if (expected > count || expected < TPM_HEADER_SIZE) + return -EIO; + +- memcpy_fromio(&buf[6], &priv->rsp[6], expected - 6); ++ memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8); + + return expected; + } +-- +2.19.1 +