Krf - A Kernelspace Randomized Faulter


KRF is a Kernelspace Randomized Faulter.
It currently supports the Linux together with FreeBSD kernels.

What?
Fault injection is a software testing technique that involves inducing failures ("faults") inward the functions called yesteryear a program. If the callee has failed to perform proper mistake checking together with handling, these faults tin effect inward unreliable application conduct or exploitable vulnerabilities.

Unlike the many userspace fault injection systems out there, KRF runs inward kernelspace via a loaded module. This has several advantages:
  • It industrial plant on static binaries, equally it does non rely on LD_PRELOAD for injection.
  • Because it intercepts raw syscalls together with non their libc wrappers, it tin inject faults into calls made yesteryear syscall(3) or inline assembly.
  • It's belike faster together with less error-prone than futzing alongside dlsym.
There are also several disadvantages:
  • You'll belike ask to laid it yourself.
  • It belike exclusively industrial plant on x86(_64), since it twiddles cr0 manually. There is belike an architecture-independent way to exercise that inward Linux, somewhere.
  • It's essentially a rootkit. You should definitely never, e'er run it on a non-testing system.
  • It belike doesn't encompass everything that the Linux heart together with soul expects of syscalls, together with may destabilize its host inward weird together with hard to reproduce ways.

How does it work?
KRF rewrites the Linux or FreeBSD organisation telephone call upwards table: when configured via krfctl, KRF replaces faultable syscalls alongside sparse wrappers.
Each wrapper therefore performs a cheque to come across whether the telephone call upwards should hold out faulted using a configurable targeting organisation capable of targeting a specific personality(2), PID, UID, and/or GID. If the procedure shouldn't hold out faulted, the master copy syscall is invoked.
Finally, the targeted telephone call upwards is faulted via a random failure function. For example, a read(2) telephone call upwards powerfulness have i of EBADF, EINTR, EIO, together with therefore on.

Setup

Compatibility
NOTE: If you lot bring Vagrant, merely occupation the Vagrantfile together with restrain to the laid steps.
KRF should piece of work on whatever recent-ish (4.15+) Linux heart together with soul alongside CONFIG_KALLSYMS=1.
This includes the default heart together with soul on Ubuntu 18.04 together with belike many other recent distros.

Dependencies
NOTE: Ignore this if you're using Vagrant.
Apart from a C toolchain (GCC is belike necessary for Linux), KRF's exclusively dependencies should hold out libelf, the heart together with soul headers, together with Ruby (for code generation).
GNU Make is required on all platforms; FreeBSD additionally requires BSD Make.
For systems alongside apt:
sudo apt install libelf-dev ruby linux-headers-$(uname -r)

Building
git clone https://github.com/trailofbits/krf && cd krf brand -j$(nproc)
or, if you're using Vagrant:
git clone https://github.com/trailofbits/krf && cd krf vagrant upwards linux && vagrant ssh linux # within the VM cd /vagrant brand -j$(nproc)
or, for FreeBSD:
git clone https://github.com/trailofbits/krf && cd krf cd vagrant upwards freebsd && vagrant ssh freebsd # within the VM cd /vagrant gmake # NOT make!

Usage
KRF has 3 components:
  • A heart together with soul module (krfx)
  • An execution utility (krfexec)
  • A command utility (krfctl)
To charge the heart together with soul module, run make insmod. To unload it, run make rmmod.
KRF begins inward a neutral state: no syscalls volition hold out intercepted or faulted until the user specifies some conduct via krfctl:
# no induced faults, fifty-fifty alongside KRF loaded ls  # tell krf to fault read(2) together with write(2) calls # Federal Reserve notation that krfctl requires root privileges sudo ./src/krfctl/krfctl -F 'read,write'  # tell krf to fault whatever programme alongside a # personality of 28 (the value laid yesteryear krfexec) sudo ./src/krfctl/krfctl -T personality=28  # may fault! ./src/krfexec/krfexec ls  # krfexec volition top away options correctly equally good ./src/krfexec/krfexec echo -n 'no newline'  # clear the fault specification sudo ./src/krfctl/krfctl -c  # clear the targeting specification sudo ./src/krfctl/krfctl -C  # no induced faults, since no syscalls are existence faulted ./src/krfexec/krfexec firefox
On FreeBSD, krfexec requires root privileges. By default, it volition effort to occupation SUDO_UID together with the username returned yesteryear getlogin_r to render to a non-root user earlier executing the target. To forcefulness a especial UID, export REAL_UID, e.g.:
REAL_UID=1000 sudo ./src/krfexec/krfexec ls

Configuration
NOTE: Most users should occupation krfctl instead of manipulating these files yesteryear hand. In FreeBSD, these same values are accessible through sysctl krf.whatever instead of procfs.

/proc/krf/rng_state
This file allows a user to read together with modify the internal acre of KRF's PRNG.
For example, each of the next volition correctly update the state:
echo "1234" | sudo tee /proc/krf/rng_state echo "0777" | sudo tee /proc/krf/rng_state echo "0xFF" | sudo tee /proc/krf/rng_state
The acre is a 32-bit unsigned integer; attempting to alter it beyond that volition fail.

/proc/krf/targeting
This file allows a user laid the values used yesteryear KRF for syscall targeting.
NOTE: KRF uses a default personality non currently used yesteryear the Linux heart together with soul yesteryear default. If you lot alter this, you lot should hold out careful to avoid making it something that Linux cares about. man ii personality has the details.
echo "0 28" | sudo tee /proc/krf/targeting
Influenza A virus subtype H5N1 personality of 28 is hardcoded into krfexec.

/proc/krf/probability
This file allows a user to read together with write the probability of inducing fault for a given (faultable) syscall.
The probability is represented equally a reciprocal, e.g. 1000 way that, on average, 0.1% of faultable syscalls volition hold out faulted.
echo "100000" | sudo tee /proc/krf/probability

/proc/krf/control
This file controls the syscalls that KRF faults.
NOTE: Most users should occupation krfctl instead of interacting alongside this file straight — the erstwhile volition perform syscall name-to-number translation automatically together with volition supply clearer mistake messages when things become wrong.
# supersede the syscall inward slot 0 (usually SYS_read) alongside its faulty wrapper echo "0" | sudo tee /proc/krf/control
Passing whatever disclose greater than KRF_NR_SYSCALLS volition drive KRF to level the entire syscall table, returning it to the neutral state. Since KRF_NR_SYSCALLS isn't necessarily predictable for arbitrary versions of the Linux kernel, choosing a large disclose (like 65535) is fine.
Passing a valid syscall disclose that lacks a fault injection wrapper volition drive the write(2) to the file to neglect alongside EOPNOTSUPP.

/proc/krf/log_faults
This file controls whether or non KRF emits heart together with soul logs on faulty syscalls. By default, no logging messages are emitted.
NOTE: Most users should occupation krfctl instead of interacting alongside this file directly.
# enable fault logging echo "1" | sudo tee /proc/krf/log_faults # disable fault logging echo "0" | sudo tee /proc/krf/log_faults # read the logging acre truthful cat /proc/krf/log_faults