DF-1989 / fix.diff
diff --git a/sys/dev/crypto/tpm/tpm_crb.c b/sys/dev/crypto/tpm/tpm_crb.c index 1111111..2222222 100644 --- a/sys/dev/crypto/tpm/tpm_crb.c +++ b/sys/dev/crypto/tpm/tpm_crb.c @@ -218,6 +218,33 @@ } } + /* + * Validate that the command and response buffers actually fit + * within the allocated MMIO BAR. The TPM reports these via CRB + * registers; a buggy or malicious implementation (common with + * software emulators) can report values that would cause OOB + * bus_space accesses in tpmcrb_transmit. + */ + bus_size_t bar_size = rman_get_size(sc->mem_res); + if (crb_sc->cmd_off >= bar_size || + crb_sc->cmd_buf_size > bar_size - crb_sc->cmd_off) { + device_printf(sc->dev, + "Command buffer exceeds BAR (off=0x%jx size=0x%jx bar=0x%jx)\n", + (uintmax_t)crb_sc->cmd_off, (uintmax_t)crb_sc->cmd_buf_size, + (uintmax_t)bar_size); + tpmcrb_detach(dev); + return (ENXIO); + } + if (crb_sc->rsp_off >= bar_size || + crb_sc->rsp_buf_size > bar_size - crb_sc->rsp_off) { + device_printf(sc->dev, + "Response buffer exceeds BAR (off=0x%jx size=0x%jx bar=0x%jx)\n", + (uintmax_t)crb_sc->rsp_off, (uintmax_t)crb_sc->rsp_buf_size, + (uintmax_t)bar_size); + tpmcrb_detach(dev); + return (ENXIO); + } + sc->transmit = tpmcrb_transmit; result = tpm20_init(sc); |