DragonFlyBSD Kernel Audit
DF-2410 / fix.diff
← back to finding ↓ download raw
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 */