⬢ DragonFlyBSD Kernel Audit
DF-4905 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/powermng/powernow/powernow.c
+++ b/sys/dev/powermng/powernow/powernow.c
@@ -185,9 +185,20 @@
 			cstate->low = PN8_PSB_TO_BATT(psb->reserved);
 			p += sizeof(struct psb_s);
 			for (i = 0; i < psb->n_pst; ++i) {
+				/* DF-4905: keep the walk inside the BIOS window --
+				 * psb->n_pst/n_states come from BIOS memory and
+				 * must not be trusted to stay within
+				 * BIOS_START..BIOS_START+BIOS_LEN. */
+				if ((uint8_t *)p + sizeof(struct pst_s) >
+				    (uint8_t *)BIOS_PADDRTOVADDR(BIOS_START + BIOS_LEN))
+					return 0;
 				pst = (struct pst_s *)p;
 				cstate->pll = pst->pll;
 				cstate->n_states = pst->n_states;
+				if ((uint8_t *)p + sizeof(struct pst_s) +
+				    2 * cstate->n_states >
+				    (uint8_t *)BIOS_PADDRTOVADDR(BIOS_START + BIOS_LEN))
+					return 0;
 				if (cpusig == pst->cpuid &&
 				    pst->fid == fid && pst->vid == vid) {
 					return (k8pnow_decode_pst(cstate,