DF-4582 / rs690_div0.c
/* * DF-4582 / DF-4583 userland reproduction of the rs690 dfixed_div * divide-by-zero. Compiles the VERBATIM kernel function * (rs690_div0_body.h) in userspace and feeds it the attacker-shaped * inputs. Expected: "Floating point exception" (SIGFPE) — the * userland twin of the kernel's divide-error (#DE) panic. * * usage: ./rs690_div0 [0|1|2] (default: all scenarios in order) */ #include <signal.h> #include <unistd.h> #include <sys/wait.h> #include "rs690_div0_body.h" static void run_scenario(int s) { struct df4582_rdev rdev; struct df4582_crtc crtc; struct rs690_watermark wm; volatile u32 sink; fprintf(stderr, "== scenario %d: entering rs690_crtc_bandwidth_compute()\n", s); df4582_setup(&rdev, &crtc, s); fprintf(stderr, "== scenario %d: mode.clock=%d kHz, sideport=%d, pm.sclk=%u\n", s, crtc.base.mode.clock, rdev.mc.igp_sideport_enabled, rdev.pm.sclk.full >> 12); rs690_crtc_bandwidth_compute(&rdev, &crtc, &wm, 0); sink = wm.lb_request_fifo_depth; fprintf(stderr, "== scenario %d: survived (fifo=%u)\n", s, sink); (void)sink; } int main(int argc, char **argv) { int first = (argc > 1) ? atoi(argv[1]) : 0; int last = (argc > 1) ? first : 2; int s; for (s = first; s <= last; s++) { pid_t p = fork(); if (p == 0) { run_scenario(s); _exit(0); } else { int st = 0; waitpid(p, &st, 0); if (WIFSIGNALED(st)) fprintf(stderr, "== scenario %d: child killed by signal %d (%s)\n\n", s, WTERMSIG(st), strsignal(WTERMSIG(st))); else fprintf(stderr, "== scenario %d: child exited %d\n\n", s, WEXITSTATUS(st)); } } return 0; } |