krf: A kernelspace randomized faulter
KRF is a Kernelspace Randomized Faulter for the Linux kernel.
Fault injection is a software testing technique that involves inducing failures (“faults”) in the functions called by a program. If the callee has failed to perform proper error checking and handling, these faults can result in unreliable application behavior or exploitable vulnerabilities.
Unlike the many userspace fault injection systems out there, KRF runs in kernelspace via a loaded module. This has several advantages:
- It works on static binaries, as it does not rely on LD_PRELOAD for injection.
- Because it intercepts raw syscalls and not their libc wrappers, it can inject faults into calls made by syscall(3) or inline assembly.
- It’s probably faster and less error-prone than futzing with dlsym.
There are also several disadvantages:
- You’ll probably need to build it yourself.
- It probably only works on x86(_64), since it twiddles cr0 manually. There is probably an architecture-independent way to do that in Linux, somewhere.
- It’s essentially a rootkit. You should definitely never, ever run it on a non-testing system.
- It probably doesn’t cover everything that the Linux kernel expects of syscalls, and may destabilize its host in weird and difficult to reproduce ways.
How does it work?
KRF rewrites the Linux system call table: when configured via krfctl, KRF replaces faultable syscalls with thin wrappers.
Each wrapper then performs a check to see whether the call should be faulted (currently personality(2) + RNG). If the process shouldn’t be faulted, the original syscall is invoked.
Finally, the targeted call is faulted via a random failure function. For example, a read(2) call might receive one of EBADF, EINTR, EIO, and so on.
Copyright (C) 2018