DF-1576 / fix.diff
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) { |