DF-1544 / harness.c
/* DF-1536/DF-1544: atom PS operand unbounded idx harness. * atom_get_src_int ATOM_ARG_PS reads idx=U8(0..255) from bytecode, then * val = get_unaligned_le32(&ctx->ps[idx]); * where ctx->ps is the caller's params buffer (e.g., atom_asic_init's * uint32_t ps[16] = 64 bytes). idx=255 -> params+1020 byte offset, * deep into kernel stack. */ #include <stdio.h> #include <stdint.h> #include <string.h> static int fixed = 0; /* Simulated caller params buffer (atom_asic_init: uint32_t ps[16] = 64 bytes) */ static uint32_t ps[16]; static uint32_t atom_ps_read(uint8_t idx, int ps_size) { if (fixed) { if (idx + 4 > ps_size) { printf("PATCHED: rejected idx=%u (ps_size=%d)\n", idx, ps_size); return 0; } } else { /* original buggy: no bounds */ } /* val = get_unaligned_le32(&ctx->ps[idx]); idx is byte offset */ if (idx >= sizeof(ps)) { printf("BUG: idx=%u reads byte offset %u into kernel stack (buffer=%zu)\n", idx, idx, sizeof(ps)); return 0xDEAD; } uint8_t *p = (uint8_t*)ps; return p[idx] | (p[idx+1]<<8) | (p[idx+2]<<16) | (p[idx+3]<<24); } int main(int argc, char **argv) { if (argc > 1 && !strcmp(argv[1], "--fixed")) fixed = 1; int ps_size = 64; /* what atom_asic_init declares */ /* attacker scenario: VBIOS op PS[255] */ uint32_t v = atom_ps_read(255, ps_size); if (fixed) { printf("RESULT: PATCHED - idx=255 rejected\n"); } else { printf("RESULT: BUGGY - idx=255 reads ps+255 (OOB by %d bytes)\n", 255-64); } return 0; } |