DragonFlyBSD Kernel Audit
DF-1576 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/drm/amd/powerplay/hwmgr/processpptables.c b/sys/dev/drm/amd/powerplay/hwmgr/processpptables.c
--- a/sys/dev/drm/amd/powerplay/hwmgr/processpptables.c
+++ b/sys/dev/drm/amd/powerplay/hwmgr/processpptables.c
@@ -848,6 +848,25 @@
 	return (const ATOM_PPLIB_POWERPLAYTABLE *)table_addr;
 }
 
+/*
+ * DF-1576: every USHORT sub-table offset is consumed as
+ * (powerplay_table + offset) with NO bounds check against
+ * hwmgr->soft_pp_table_size.  A malicious VBIOS (or root poking
+ * the pp_table sysfs) can thus point us past the end of the table.
+ * Use this helper before each offset dereference.
+ */
+static inline bool pp_offset_in_bounds(const struct pp_hwmgr *hwmgr,
+                                       uint16_t offset, size_t want)
+{
+	if (hwmgr->soft_pp_table_size == 0)
+		return true;	/* unbounded (smu_atom fetch): trust */
+	if ((size_t)offset > hwmgr->soft_pp_table_size)
+		return false;
+	if (want > hwmgr->soft_pp_table_size - offset)
+		return false;
+	return true;
+}
+
 int pp_tables_get_response_times(struct pp_hwmgr *hwmgr,
 				uint32_t *vol_rep_time, uint32_t *bb_rep_time)
 {