--- a/sys/dev/powermng/powernow/powernow.c +++ b/sys/dev/powermng/powernow/powernow.c @@ -249,6 +249,13 @@ break; } } + /* DF-4903: no state matched (e.g. k8_get_curfreq()'s -1 + * became UINT_MAX) -- do not fall through to the tail read + * below, which would index state_table[n_states] + * (uninitialised for n_states < 16) and leak a heap word + * into the world-readable sysctl. */ + if (i == cstate->n_states) + return (EINVAL); if (fid == cfid && vid == cvid) { cpuspeed = freq; return 0; @@ -389,7 +396,12 @@ } kprintf(" MHz\n"); k8pnow_current_state = cstate; - k8_powernow_setperf(k8_get_curfreq()); + { + int curfreq = k8_get_curfreq(); + + if (curfreq > 0) + k8_powernow_setperf(curfreq); + } } else { kfree(cstate, M_DEVBUF); kprintf("powernow: no power states found\n");