DF-1534 / harness.c
/* DF-1534/DF-1542: atom_op_calltable unbounded recursion harness. * Mirrors the source-level recursion structure of atom_execute_table_locked. * Original source has NO depth guard, so a self-referential table (table[N] * starts with CALL_TABLE N) recurses until stack exhaustion. * * Real kernel stack is 16KB. Each atom_execute_table_locked frame allocates * an atom_exec_context (~48 bytes), callsite state (~50 bytes), plus C frame * overhead (~50-150 bytes) -> ~150-250 bytes/frame. * * 16KB / 200 bytes = ~80 frames until stack overflow -> fatal double fault. * * This harness does NOT actually overflow (we cap the demo at 200 calls so * the shell survives); instead it shows that the unpatched code recurses * indefinitely while the patched code aborts at depth 20. */ #include <stdio.h> #include <stdlib.h> static int fixed = 0; static int max_depth = 0; static const int CAP = 500; /* demo ceiling so harness survives */ static int op_calltable(int idx, int depth); static int execute_table_locked(int index, int depth); static int op_calltable(int idx, int depth) { /* In real VBIOS, this is reached if U16(cmd_table+4+2*idx) != 0 */ return execute_table_locked(idx, depth + 1); } static int execute_table_locked(int index, int depth) { if (depth > max_depth) max_depth = depth; if (fixed && depth > 20) { return -1; /* patched: -EINVAL */ } if (depth > CAP) { return -1; /* harness safety cap */ } /* table 3 body: CALL_TABLE 3 (self-recursion) */ if (index == 3) { return op_calltable(3, depth); } return 0; } int main(int argc, char **argv) { if (argc > 1 && !strcmp(argv[1], "--fixed")) fixed = 1; int r = execute_table_locked(3, 0); if (fixed) { printf("max_recursion_depth_reached=%d (capped at 20)\n", max_depth); printf("RESULT: PATCHED - recursion_depth guard aborts at depth 20 (-EINVAL)\n"); } else { /* In real kernel: would hit 16KB stack limit / fatal double fault * long before CAP. We cap at 500 here only so the harness survives. */ printf("max_recursion_depth_reached=%d (capped by harness at %d)\n", max_depth, CAP); printf("RESULT: BUGGY - no depth guard; real kernel stack overflows at ~80 frames\n"); } return 0; } |