DF-2410 / fix.diff
diff --git a/sys/dev/crypto/tpm/tpm_crb.c b/sys/dev/crypto/tpm/tpm_crb.c --- a/sys/dev/crypto/tpm/tpm_crb.c +++ b/sys/dev/crypto/tpm/tpm_crb.c @@ -195,6 +195,23 @@ crb_sc->cmd_buf_size = RD4(sc, TPM_CRB_CTRL_CMD_SIZE); crb_sc->rsp_buf_size = RD4(sc, TPM_CRB_CTRL_RSP_SIZE); + /* Validate the TPM-reported offsets/sizes against the MMIO BAR mapping + so a buggy or malicious TPM/emulator cannot drive the region stream + accesses in tpmcrb_transmit off the end of the mapping. */ + { + 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 || + crb_sc->rsp_off > bar_size || + crb_sc->rsp_buf_size > bar_size - crb_sc->rsp_off) { + device_printf(dev, "TPM CRB buffer offsets/sizes exceed BAR\n"); + bus_release_resource(dev, SYS_RES_MEMORY, + sc->mem_rid, sc->mem_res); + return (ENXIO); + } + } + tpmcrb_relinquish_locality(sc); /* Emulator returns address in acpi space instead of an offset */ |