DF-1535 / harness.c
/* DF-1535/DF-1543: atom FB scratch u32 wrap OOB harness. * Replicates: gctx->scratch[(fb_base/4)+idx] guarded by * if ((fb_base + idx*4) > scratch_size_bytes) * fb_base is u32. With fb_base=0xFFFFFFFC idx=1, sum wraps to 0 (passes * guard), then access at scratch[(fb_base/4)+idx] = scratch[0x3FFFFFFF+1] * is a wild OOB. */ #include <stdio.h> #include <stdint.h> #include <string.h> static int scratch_size_bytes = 20480; static int fixed = 0; static int atom_fb_read(uint32_t fb_base, uint8_t idx) { /* original buggy: u32+u32 wraps */ if (!fixed) { if ((fb_base + (idx * 4)) > (uint32_t)scratch_size_bytes) { return -1; /* rejected */ } } else { /* patched: u64 math */ if ((uint64_t)fb_base + (uint64_t)(idx * 4) > (uint64_t)scratch_size_bytes) { return -1; } } /* would access gctx->scratch[(fb_base/4) + idx] */ uint32_t dword_off = (fb_base / 4) + idx; printf(" access scratch[%u] (alloc dwords=5120)\n", dword_off); return (int)dword_off; } int main(int argc, char **argv) { if (argc > 1 && !strcmp(argv[1], "--fixed")) fixed = 1; /* attacker scenario: VBIOS sets fb_base = 0xFFFFFFFC via WS[FB_WINDOW] */ uint32_t evil_fb = 0xFFFFFFFC; uint8_t evil_idx = 1; printf("scratch_size_bytes=%d (alloc dwords=5120)\n", scratch_size_bytes); int rc = atom_fb_read(evil_fb, evil_idx); if (fixed) printf("RESULT: PATCHED - u64 guard rejects fb_base=0x%x idx=%u\n", evil_fb, evil_idx); else if (rc < 0) printf("RESULT: BUG (no overflow seen)\n"); else printf("RESULT: BUGGY - guard bypassed (0xFFFFFFFC + 4 = 0 wraps to 0 <= 20480)\n"); return 0; } |