The ST33ZP24 driver parses TPM command and response headers from byte
transport buffers. st33zp24_recv() reads the response size from bytes
2..5 of the TPM header, and st33zp24_send() reads the command ordinal
from bytes 6..9 when IRQ mode waits for command completion.
Those fields are 32-bit big-endian protocol fields, but their TPM
header offsets are not 32-bit aligned: the header starts with a 2-byte
tag, so both offsets 2 and 6 are 2 modulo 4. Even if the caller buffer
is 4-byte aligned, casting buf + 2 or buf + 6 to __be32 * still creates
a misaligned typed access.
Use get_unaligned_be32() for both TPM header fields.
This issue was detected by our static analysis tool and confirmed by
manual audit. A focused UBSAN alignment validation of the same typed
load shape reported a misaligned __be32 access in st33zp24_recv().
Fixes: bf38b8710892 ("tpm/tpm_i2c_stm_st33: Split tpm_i2c_tpm_st33 in 2 layers
(core + phy)")
Cc: [email protected]
Signed-off-by: Runyu Xiao <[email protected]>
---
drivers/char/tpm/st33zp24/st33zp24.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/char/tpm/st33zp24/st33zp24.c
b/drivers/char/tpm/st33zp24/st33zp24.c
index e2b7451ea7cc..2d74f30c2fc0 100644
--- a/drivers/char/tpm/st33zp24/st33zp24.c
+++ b/drivers/char/tpm/st33zp24/st33zp24.c
@@ -18,6 +18,7 @@
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/slab.h>
+#include <linux/unaligned.h>
#include "../tpm.h"
#include "st33zp24.h"
@@ -364,7 +365,7 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned
char *buf,
goto out_err;
if (chip->flags & TPM_CHIP_FLAG_IRQ) {
- ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
+ ordinal = get_unaligned_be32(buf + 6);
ret = wait_for_stat(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
tpm_calc_ordinal_duration(chip, ordinal),
@@ -400,7 +401,7 @@ static int st33zp24_recv(struct tpm_chip *chip, unsigned
char *buf,
goto out;
}
- expected = be32_to_cpu(*(__be32 *)(buf + 2));
+ expected = get_unaligned_be32(buf + 2);
if (expected > count || expected < TPM_HEADER_SIZE) {
size = -EIO;
goto out;
--
2.34.1