DF-4905 / fix.diff
--- 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, |