Master the fundamental concepts of system calls & kernel interface through this focused micro-challenge.
Kernel syscall handlers must validate every user pointer and length. Fuzzers send garbage arguments (negative lengths, unmapped addresses, wrong fd types) hunting for panics or privilege leaks.
Effective campaigns:
For example, calling read(-1, (void*)1, SIZE_MAX) should return EBADF or EFAULT, never crash the kernel.
Google's syzkaller has found thousands of real Linux kernel bugs this way, including use-after-free and out-of-bounds vulnerabilities that earned CVEs, precisely by fuzzing syscall arguments like the ones you generate here (NULL pointers, negative fds, boundary sizes). The crash-catching pattern with sigsetjmp/siglongjmp mirrors how real fuzzing harnesses keep running after a target syscall corrupts memory instead of taking down the entire fuzzer process.
Before you call the implementation done, walk failure modes on purpose. Test empty structures, single-element edge cases, maximum concurrency, and errno paths that must not crash the program. OS code usually fails in production when happy-path tests pass but invariants break under contention or memory pressure.
Keep structures small and name fields after kernel counterparts when possible. That lets you read man pages and kernel source side by side while you work. Print observable events during development; remove noisy logs once tests pass reliably.
You will implement a userspace harness that mutates syscall arguments and records outcomes. The task asks you to classify results into expected errno vs unexpected signals.
Implement syscall fuzzer.
Requirements:
Success Criteria:
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
All starter code and reference implementations are available for your local setup.
View on Github