Giter Club home page Giter Club logo

kbdysch's Introduction

kBdysch

kBdysch is a collection of fast Linux kernel specific fuzzing harnesses supposed to be run in userspace in a guided fuzzing manner. It was designed with AFL compatibility in mind but AFL is not required to use this project.

Fuzzing targets

Currently, kBdysch is capable of testing the following aspects of the kernel:

  • file system implementations (for those residing on a single block device)
    • use one file system implementation as a model for testing some other one. Just like proposed in AFL documentation but for the entire FS driver...
  • eBPF verifier
  • HID subsystem via uhid emulated device
  • partition table parsers

Design

The main design ideas are:

  • reuse Linux Kernel Library project to run almost any part of the Linux kernel in user space just like a regular library
  • reuse Syzkaller syscall descriptions for invoker generation
  • use GNU pth library instead of classic Pthread so all the code is executed in a single OS thread
    • no need to worry about restoring existing threads after fork() being executed by a AFL's forkserver. This is especially useful since the kernel library may start in a matter of seconds, not microseconds, and spawn some essential threads early in the boot sequence
    • bonus: you have much higher stability of behavior because now only discrete thread switch points are possible and no really concurrent memory accesses possible at all
  • implement many different ways to detect abnormal behavior
    • crash, the classical one: if crashed then failed
    • but now we have almost full control over the host-ops (block device operations, printk, etc.)! so, ...
    • suspicious output: if printed some word (error, corruption, etc.) then failed
    • poisoned memory: if some output buffer returned by the kernel contains many poisoned memory marker bytes in a row then failed (existed in the original implementation but not yet moved to the refactored one)
    • panic(), BUG(), etc. triggered
    • misc minor sanity checking, such as "if negative syscall return value signifies error condition, then it should always return either non-negative value or a valid errno code"
    • ... and last, but in fact the original idea of this fuzzer...
    • behavioral difference: this is strictly file system fuzzing related checker, but it can detect some subtle data corruptions by carefully separating operations on different file systems and comparing the results of performing the same syscall sequence on them, considering every not-whitelisted discrepancy as a bug. This can find logical errors even when they do not manifest themselves as a bug on its own.
  • since we proxy the block layer accesses to RAM-backed disk images anyway, we can record the accessed ranges to mutate it on image remount
    • doing this when the volume is mounted makes some sense but probably not too much, since it then simulates way too malicious (or just too buggy) block device and is not implemented for now
    • not compatible with many of the checkers listed above, especially the behavior difference

Pre-existing works

kBdysch is not a unique approach. At least, there exist a Janus fuzzer that uses both syscall invokers and image mutators being applied to LKL. As far as I understand, their approach is slightly different:

  • Janus tests one filesystem image at a time, while kBdysch can compare one implementation against another similar one
  • test case shape:
    • Janus test case has a shape of (Blob, Seq[Mutation], Seq[Syscall]) (apply some existing mutations to the FS image blob, invoke syscall sequence, then record new mutations naturally produced by the kernel)
    • kBdysch uses the shape of (Blob, Seq[Either[Mutation, Syscall]]) (load some reference image, then in each forked child apply a sequence of operations to it from clean state, with one of operation being mutating touched parts)
  • metadata handling:
    • Janus uses hand-written metadata parsers. This can handle checksum-protected metadata in an effective manner
    • kBdysch just records areas of image being accessed before remount (this can be handled trivially since we are already proxying block ops) to mutate them in the hope that they can be accessed again (at least with similar system calls) after remount . On one hand, this may be simply rejected by checksum-protected kernel metadata parsers. On the other hand, this allows much more trivial exploration of new file systems (for those not requiring specific mount helpers, this may be achieved in a matter of minutes)

kBdysch is more tending to an approach of requiring as less manual work as possible while more relying on similar to Pulling JPEGs out of thin air.

Building from sources

To use the bundled invoker, just run the build.sh script.

In case you would want to modify the syscall descriptions, use update_invokers.sh script. You need Java installed in this case (and it will download all other Scala-related stuff on itself).

See troubleshooting.md if something goes wrong.

Optional dependencies:

  • libpcap

Bugs

Technically, this fuzzer has not found anything yet at the time of writing this README, since it is a partial rewrite of the original fuzzer that has found a couple tens of bugs but had quite awful code. I tried to closely replicate its behavior, so it is expected to find roughly the same bugs as its predecessor.

On the bugs found by its predecessor, almost anything matched in git log with something like Reported-by:.*anatoly.trosinenko is found via this approach (but some report can lead to 2-3 commits).

Why such name?

This is not a random sequence of characters. And I don't try to fuzz this project users' ability to read English words, as well. It is merely "K for Kernel" followed by a transliterated Russian word БДЫЩ! (an onomatopoeia denoting the sound of some crash, similar to BOOM!). Just like "borsch" but "bdysch".

kbdysch's People

Contributors

atrosinenko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kbdysch's Issues

make lkl failed

On ubuntu server 18.04
I just run ./build.sh
when make -C tools/lkl

/home/uuu/kernel/kbdysch/lkl-linux/tools/lkl//include/lkl/asm/syscall_defs.h: In function ‘lkl_sys_inotify_init’:
/home/uuu/kernel/kbdysch/lkl-linux/tools/lkl//include/lkl/asm/syscalls.h:288:22: error: ‘__lkl__NR_inotify_init’ undeclared (first use in this function); did you mean ‘__lkl__NR_inotify_init1’?
   return lkl_syscall(__lkl__NR##name, params);        \
                      ^
/home/uuu/kernel/kbdysch/lkl-linux/tools/lkl//include/lkl/asm/syscalls.h:325:40: note: in expansion of macro ‘LKL_SYSCALL0’
 #define LKL_SYSCALL_DEFINE0(name, ...) LKL_SYSCALL0(name)

Cannot load eBPF program

On ubuntu 18.04
I've built the lkl.so and linked the kbdysch runtime successfully with the USE_INVOKERS option OFF.

But when I test the bpffuzz with following cmd

./bpffuzz init=/bin/sh < ../../ebpf_data/data

It shows that

[    0.000000] Linux version 5.3.0+ (happy@ubuntu) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #1 Sun May 31 22:20:21 PDT 2020
[    0.000000] memblock address range: 0x7fdf7c000000 - 0x7fdf7ffff000
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 16159
[    0.000000] Kernel command line: init=/bin/sh
[    0.000000] Dentry cache hash table entries: 8192 (order: 4, 65536 bytes, linear)
[    0.000000] Inode-cache hash table entries: 4096 (order: 3, 32768 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory available: 64500k/65532k RAM
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS: 4096
[    0.000000] lkl: irqs initialized
[    0.000000] clocksource: lkl: mask: 0xffffffffffffffff max_cycles: 0x1cd42e4dffb, max_idle_ns: 881590591483 ns
...
Mounting all...
Cannot load eBPF program: Invalid system call number

seems Invalid system call number,
but I check the syscall invoke instruction again

INVOKE_SYSCALL(state, bpf, BPF_PROG_LOAD , (long)&attr, sizeof(attr));

replace the BPF_PROG_LOAD with LKL_BPF_PROG_LOAD also fail.

undefined reference to `pth_self'

after installing GNU Pth 2.0.7 and make, it occured errors like these:

osboxes@osboxes:~/kernel-fuzz/kbdysch/lkl-linux$ make -C tools/lkl -j8 make: Entering directory '/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl' afl-clang-fast++2.59d by <[email protected]> LINK /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/tests/boot /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/liblkl.a(liblkl-in.o): in function _gettid':
/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:161: undefined reference to pth_self' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/liblkl.a(liblkl-in.o): in function thread_self':
/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:122: undefined reference to pth_self' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/liblkl.a(liblkl-in.o): in function tls_get':
/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:156: undefined reference to pth_key_getdata' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/liblkl.a(liblkl-in.o): in function thread_exit':
/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:109: undefined reference to pth_exit' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/liblkl.a(liblkl-in.o): in function thread_create':
/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:98: undefined reference to pth_spawn' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/liblkl.a(liblkl-in.o): in function tls_set':
/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:149: undefined reference to pth_key_setdata' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/liblkl.a(liblkl-in.o): in function tls_free':
/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:143: undefined reference to pth_key_delete' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/liblkl.a(liblkl-in.o): in function tls_alloc':
/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:134: undefined reference to pth_key_create' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/liblkl.a(liblkl-in.o): in function thread_join':
/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:114: undefined reference to pth_join' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/liblkl.a(liblkl-in.o): in function mutex_unlock':
/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:87: undefined reference to pth_mutex_release' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/liblkl.a(liblkl-in.o): in function mutex_lock':
/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:82: undefined reference to pth_mutex_acquire' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/liblkl.a(liblkl-in.o): in function mutex_alloc':
/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:75: undefined reference to pth_mutex_init' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/liblkl.a(liblkl-in.o): in function sem_down':
/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:61: undefined reference to pth_mutex_acquire' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:63: undefined reference to pth_cond_await'
/usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:65: undefined reference to pth_mutex_release' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/liblkl.a(liblkl-in.o): in function sem_up':
/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:52: undefined reference to pth_mutex_acquire' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:56: undefined reference to pth_mutex_release'
/usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:55: undefined reference to pth_cond_notify' /usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:56: undefined reference to pth_mutex_release'
/usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/liblkl.a(liblkl-in.o): in function sem_alloc': /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:37: undefined reference to pth_mutex_init'
/usr/bin/ld: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/lib/posix-host-pth.inc.c:39: undefined reference to pth_cond_init' collect2: error: ld returned 1 exit status make: *** [Makefile:82: /home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl/tests/boot] Error 1 make: Leaving directory '/home/osboxes/kernel-fuzz/kbdysch/lkl-linux/tools/lkl'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.