Fuzzing the Linux kernel
Andrey Konovalov, xairy.io
�May 20th 2021
Who am I?
My experience with Linux kernel fuzzing
Agenda
Concepts, from simplest to most involved
ФСТЭК
Fuzzing
Fuzzing
Generate
input
Execute
program
Crash?
No
Yes
Great!
Fuzzing an XML parser
Generate
random
XML file
Feed into
parser
Crash?
No
Yes
Great!
Programs
Fuzzing
Kernel fuzzing
Fuzzing the Linux kernel:
Legacy
Running the kernel
Running the kernel
| Physical device | VM (e.g. QEMU) |
Fuzzing surface | Native (includes device drivers) | Only what the VM supports |
Management (restarting, debugging, getting kernel logs) | Hard; hardware gets bricked | Easy |
Scalability | Buy more devices | Spawn more VMs |
QEMU or physical device
Kernel inputs
Kernel inputs
vmlinux
module.ko
Userspace
Kernel
Syscalls (open, write, ioctl, …)
QEMU or physical device
Syscalls
Execute a binary
Legacy approach
Works everywhere!
QEMU or physical device
Syscalls
Execute a binary
Generating inputs
Generating inputs for userspace apps
if (input[0] == '<')
if (input[1] == 'x')
if (input[2] == 'm')
if (input[3] == 'l')
// Need to reach at least here.
Random inputs
Better inputs
XML_GRAMMAR = {
"<start>": ["<xml-tree>"],
"<xml-tree>": ["<text>", "<xml-open-tag><xml-tree><xml-close-tag>",
"<xml-openclose-tag>", "<xml-tree><xml-tree>"],
"<xml-open-tag>": ["<<id>>", "<<id> <xml-attribute>>"],
"<xml-openclose-tag>": ["<<id>/>", "<<id> <xml-attribute>/>"],
"<xml-close-tag>": ["</<id>>"],
"<xml-attribute>" : ["<id>=<id>", "<xml-attribute> <xml-attribute>"],
"<id>": ["<letter>", "<id><letter>"],
"<text>" : ["<text><letter_space>","<letter_space>"],
"<letter>": srange(string.ascii_letters + string.digits +"\""+"'"+"."),
"<letter_space>": srange(string.ascii_letters + string.digits +"\""+"'"+" "+"\t"),
}
Structured inputs
Generating kernel inputs
int fd = open("/dev/something", …);
ioctl(fd, SOME_IOCTL, &{0x10, ...});
close(fd);
Example of a kernel input
int fd = open("/dev/something", …);
ioctl(fd, SOME_IOCTL, &{0x10, ...});
close(fd);
Example of a kernel input
int fd = open("/dev/something", …);
ioctl(fd, SOME_IOCTL, &{0x10, ...});
close(fd);
Example of a kernel input
int fd = open("/dev/something", …);
ioctl(fd, SOME_IOCTL, &{0x10, ...});
close(fd);
Example of a kernel input
int fd = open("/dev/something", …);
ioctl(fd, SOME_IOCTL, &{0x10, ...});
close(fd);
Example of a kernel input
API-aware fuzzing
QEMU or physical device
Syscalls
Execute a binary
API-awareness
Kernel panics
while (true) syscall(…)
Legacy approach
This is Trinity!
Fuzzing the Linux kernel:
Foundation
QEMU or physical device
Syscalls
Execute binary
Foundational approach
QEMU or physical device
Syscalls
Execute binary
Generating inputs
Better inputs
Better inputs
Mutate according to the structure (e.g. insert/remove XML tags)
Coverage-guided generation
Corpus of inputs
Choose a random input
Mutate
New cover?
Add to corpus
Execute
No
Yes
Applying to the kernel
QEMU or physical device
Syscalls
Execute binary�API-awareness + KCOV
Running the kernel
Detecting kernel bugs
Dynamic bug detectors for the kernel
QEMU or physical device
Syscalls
Execute binary�API-awareness + KCOV�KASAN and others
Running the kernel
Automation
QEMU or physical device
Syscalls
Execute binary
API-awareness + KCOV
KASAN and others
All that mentioned fancy stuff
Foundational approach
This is syzkaller! (in its base)
Fuzzing the Linux kernel:
Charged
Running kernel code in userspace
Kernel inputs: syscalls
vmlinux
module.ko
Userspace
Kernel
Syscalls (open, write, ioctl, …)
Kernel inputs: external
vmlinux
module.ko
Hardware / Firmware
Userspace
Kernel
Network packets, USB devices, ...
Injecting external inputs
Input structure: unusual syscalls
Input structure: external
Collecting code coverage
Relevant code coverage
Beyond code coverage
Better inputs
Collecting a corpus of samples
Detecting more bugs
Fuzzing approaches
Fuzzing approaches
Reusing a userspace fuzzer
Using syzkaller
syzkaller is extensible
Writing a fuzzer from scratch
Fuzzing tips
Is my fuzzer good?
Read the code
Fast vs smart
Final note
Writing fuzzers is engineering
Linux kernel fuzzing materials
Thank you for your attention!
Andrey Konovalov, xairy.io
�May 20th 2021