DF-1354 / trigger.c
/* DF-1354 vega12_apply_clocks_adjust_rules mclk_latency count underflow */ #include <stdio.h> #include <stdint.h> #include <string.h> #define MAX_REGULAR_DPM_NUMBER 16 struct mclk_lat { uint32_t count; uint32_t entries[MAX_REGULAR_DPM_NUMBER]; }; struct dpm_table { uint32_t count; uint32_t levels[MAX_REGULAR_DPM_NUMBER]; }; static uint32_t oob_reads_vuln; static void apply_vuln(struct dpm_table *d, struct mclk_lat *m){ /* count is uint32, defaults 0 ; count - 1 wraps to 0xFFFFFFFF */ for (uint32_t i = 0; i < m->count - 1; i++){ if (i >= MAX_REGULAR_DPM_NUMBER) oob_reads_vuln++; /* reads m->entries[i] and d->levels[i] OOB */ } } static int apply_fixed(struct dpm_table *d, struct mclk_lat *m){ if (d->count == 0) return -1; for (uint32_t i = 0; i < m->count && i < d->count && i < MAX_REGULAR_DPM_NUMBER - 1; i++){ /* safe */ } return 0; } int main(void){ struct dpm_table d; struct mclk_lat m; memset(&d, 0, sizeof(d)); memset(&m, 0, sizeof(m)); /* count == 0 from kzalloc -> wraps */ printf("== BEFORE-FIX (vulnerable) ==\n"); /* simulate the wrap by capping iterations to avoid real hang */ m.count = 0; /* emulate: count-1 = 0xFFFFFFFF; we stop at 100 to demo OOB */ for (uint32_t i=0; i<100; i++) if (i >= MAX_REGULAR_DPM_NUMBER) oob_reads_vuln++; printf("BUG: count=%u, count-1 wraps to %u, loop reads entries[i]/dpm_levels[i] OOB (OOB reads in first 100 iters: %u)\n", m.count, m.count - 1, oob_reads_vuln); printf("== AFTER-FIX ==\n"); int rc = apply_fixed(&d, &m); printf("FIX: count==0 -> return -EINVAL, no OOB reads (rc=%d)\n", rc); return 0; } |