⬢ DragonFlyBSD Kernel Audit
DF-4903 / fix.diff
← back to finding ↓ download raw
--- 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");