Code Monkey home page Code Monkey logo

buzzer's Introduction

Buzzer - An eBPF Fuzzer toolchain

ci_status

Buzzer is a fuzzer toolchain that allows to write eBPF fuzzing strategies.

A Fuzzing strategy is a way to generate random eBPF Programs and then validate that they don't have unexpected behaviour.

To run the fuzzer follow the next steps

  1. Install bazel.

  2. Install clang

  3. Setup the correct CC and CXX env variables

    export CC=clang
    export CXX=clang++
    
  4. Run

    bazel build :buzzer
    
  5. Run buzzer either as root:

    sudo ./bazel-bin/buzzer_/buzzer
    

    OR with CAP_BPF:

    sudo setcap CAP_BPF=eip bazel-bin/buzzer_/buzzer
    ./bazel-bin/buzzer_/buzzer
    

Documents:

Trophies

Did you find a cool bug using Buzzer? Let us know via a pull request! We'd like to collect all issues discovered with this framework under this section.

  • CVE-2023-2163: An error in the branch pruning logic of the eBPF verifier can cause unsafe paths to not be explored. The unsafe pruned paths are the actual paths taken at runtime which causes a mismatch in what the verifier thinks the values of certain registers are versus what they actually are. This mismatch can be abused to read/write arbitrary memory in the kernel by using the confused registers as base registers for memory operations.

buzzer's People

Contributors

kost avatar meadori avatar paulo-lopes-estevao avatar thatjiaozi 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  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

buzzer's Issues

Run buzzer in the vm and get "Fuzzer run no 0"

Hi, I prepared the environment as the buzzer and syzkaller docs describe, and it goes smoothly.
but when I run buzzer in the vm, it gets "Fuzzer run no 0" as bellows:

root@syzkaller:~# ls
buzzer	sourceFiles  vmlinux
root@syzkaller:~# ./buzzer 
running fuzzing strategy parse_verifier_log
Fuzzer run no 0.

Besides, I can only see "404 page not found" on the webpage http://localhost:8080/.
Is the buzzer running? what should I have seen in this step?
I don't know what happens, could you please give me some advice?
Thanks.

run with coverage enabled but failed

env

uname: 5.19.17
os-release:

root@syzkaller:~# cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
qemu-system-x86_64 \
  -m 8G \
  -smp 4 -cpu host \
  -kernel /home/g0dA/kernel/linux-5.19.17/arch/x86/boot/bzImage \
  -append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
  -drive file=/home/g0dA/kernel/debian/debian.img,format=raw \
  -net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22,hostfwd=tcp:127.0.0.1:8888-:8080 \
  -net nic,model=e1000 \
  -enable-kvm \
  -nographic \
  -pidfile vm.pid

Error

root@syzkaller:~# ls
buzzer	sourceFiles  vmlinux
root@syzkaller:~# ./buzzer
......
2023/05/03 02:09:54 failed to init control unit: Run program did not succee

and have output like this:

program flaked1974.                               
Writing verifier log to "/tmp/verifier-log-302911802".
Writing eBPF binary to "/tmp/ebpf-binary-3260864109".
"strconv.Atoi: parsing \"?\": invalid syntax"

Make complaints....Compiling is really cumbersome and requires gcc 12+

Integrate with syzkaller

syzkaller is a coverage-guided OS kernel fuzzer. It can generate BPF programs of low quality and could benefit from a high-quality BPF generator. It won't be as efficient as Buzzer in stressing BPF subsystem itself, but will uncover bugs in more complex interactions between BPF programs and other kernel subsystems.

I have a prototype for integration, which you can mostly ignore except for the proposed interface between syzkaller and Buzzer:

// This is supposed to be buzzer.Generate.
// progType is the program type (BPF_PROG_TYPE_SOCKET_FILTER/KPROBE/...).
// oldInsns is the program for mutation, if empty, generate a new one.
// Returns new/mutated program and number of used map fd's in bpf_attr::fd_array.
func BuzzerGenerate(progType int, rnd *rand.Rand, oldInsns []uint64) (insns []uint64, maps int)

Buzzer and syzkaller has some model mismatch as syzkaller generates and mutates programs offline. So it's not possible to embed actual map fd's into the program (they don't exist yet, and we are not even running on the target machine).
So I restricted it to use of only bpf_attr::fd_array, which syzkaller will fill with requested number of fd's later.
It is possible to use fd's embed in the program, but it will require some for of a-la ELF relocations (buzzer will need to say what offsets in the program should contain fd's and which of these refer to the same/different maps). I decided to left this out for now.

Any other ideas on how to design the interface? Anything I've missed? Do we need attach type here? Or map types? Or anything to make it possible to call C functions from the BPF program?

CC @a-nogikh @tarasmadan

`bazel build :buzzer` fails on M1 Macs

Traceback:

36 $ bazel build :buzzer

INFO: Analyzed target //:buzzer (12 packages loaded, 42 targets configured).
INFO: Found 1 target...
ERROR: /Users/piotrostr/buzzer/ebpf_ffi/BUILD:21:11: Compiling ebpf_ffi/ffi.cc failed: (Exit 1): cc_wrapper.sh failed: error executing command (from target //ebpf_ffi:ebpf_ffi) external/local_config_cc/cc_wrapper.sh -U_FORTIFY_SOURCE -fstack-protector -Wall -Wthread-safety -Wself-assign -Wunused-but-set-parameter -Wno-free-nonheap-object -fcolor-diagnostics ... (remaining 41 arguments skipped)

Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
In file included from ebpf_ffi/ffi.cc:15:
./ebpf_ffi/ffi.h:22:10: fatal error: 'linux/bpf.h' file not found
#include <linux/bpf.h>
         ^~~~~~~~~~~~~
1 error generated.
Target //:buzzer failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 2.488s, Critical Path: 0.97s
INFO: 14 processes: 8 internal, 6 darwin-sandbox.
FAILED: Build did NOT complete successfully

Environment:

  • bazel 6.2.0, installed with bazelisk
  • go version go1.20.3 darwin/arm64

404 page not found on my metrics server webpage

Hi!
I've had buzzer running for 10+ hours and my metrics server shows no information (i.e., 404 page not found).
I compiled my kernel with kcov and kasan as the syzkaller instructions, and built the bullseye image,
and replace the PATH_TO_DEBIAN_IMAGE and PATH_TO_KERNEL_REPO with absolute path like /home/xxx/workspace/image/ and /home/xxx/workspace/kernel/, and my kernel build .config includes:
"CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_KCOV=y
CONFIG_KASAN=y"

I'm not sure where the problem is. It might be similar to issue/37, but I haven't understood the solution. Please provide some assistance. Thank you.

Create a wrapper around ebpf helper functions to make it easier to fuzz them

Currently working at creating wrappers around ebpf instructions to make the creation of ebpf programs friendlier. Once this work is landed, we would invoke a helper function (e.g map_lookup_element) like this:

Mov64(R1, ptr_to_map)
Mov64(R2, key)
CallFunction(map_lookup_element)

While doing this I noticed we could also create wrappers around ebpf helper functions, that would set up the registers in the right state, so the above example would turn into:

bpf_map_lookup_elemen(ptr_to_map, key)  

Landing this work would be dependent on the refactoring that I am working on right now, so opening this issue for tracking purposes.

Bit Shift operations generate a high ratio of invalid program failures

While manually testing the fuzzer I noticed that bit shift operations generate a lot of invalid programs due to an invalid shift amount (e.g negativa values or values over 32/64).

The solution is simple: whenever we generate a bit shift operation, make sure the shift amount is always between [1, 31] or [1,63] depending on the instruction class.

Make eBPF program writing easier

Currently, this pattern gets repeated often to write an ebpf program:

var root, ptr, next ebpf.EBPFOperation
root := ALUIMMOperation(...)
ptr = root

next := ...
ptr.SetNextInstruction(next)
ptr = next 

...

Ideally, programs should be built in a more readable and easier to write way, for example:

newEBPFSequence(
MOV64(R0, 0),
MOV64(R1, R0),
MUL64(R1, 10),
...
)

buzzer always raises error "Bad address"

It is an excellent work. But I came accross some trouble when using Buzzer.
I successfully compiled and installed Buzzer according to the REAME.
However, it kept rasing error "Bad address" when executing eBPF prog.

My environment: OS 20.04, gcc-10

I configured Buzzer with the default settings and made sure that the BPF syscall is accessible as BCC worked fine.

Do you have any idea?

Support MovReg64

The current implementation cannot support the MovReg64 well.

In pkg/ebpf/alu_instructions.go, although there is a function called MovRegImm64, however, the arguments only supports the imm32.

// MovRegImm64 sets re to the specified value
func MovRegImm64(reg *Register, imm int32) *AluImmInstruction {
	return NewAluImmInstruction(AluMov, InsClassAlu64, reg, imm)
}

Example

For the following simple ebpf program

#define BPF_NO_GLOBAL_DATA
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>

typedef unsigned int u32;
typedef int pid_t;
const pid_t pid_filter = 0;

char LICENSE[] SEC("license") = "Dual BSD/GPL";

SEC("tp/syscalls/sys_enter_write")
int handle_tp(void *ctx)
{
 pid_t pid = bpf_get_current_pid_tgid() >> 32;
 if (pid_filter && pid != pid_filter)
  return 0;
 bpf_printk("BPF triggered sys_enter_write from PID %d.\n", pid);
 return 0;
}

The disassembled result is:

Disassembly of section tp/syscalls/sys_enter_write:

0000000000000000 <handle_tp>:
       0:	85 00 00 00 0e 00 00 00	call 0xe
       1:	b7 01 00 00 64 2e 0a 00	r1 = 0xa2e64
       2:	63 1a f8 ff 00 00 00 00	*(u32 *)(r10 - 0x8) = r1
       3:	18 01 00 00 6f 6d 20 50 00 00 00 00 49 44 20 25	r1 = 0x2520444950206d6f ll
       5:	7b 1a f0 ff 00 00 00 00	*(u64 *)(r10 - 0x10) = r1
       6:	18 01 00 00 77 72 69 74 00 00 00 00 65 20 66 72	r1 = 0x7266206574697277 ll
       8:	7b 1a e8 ff 00 00 00 00	*(u64 *)(r10 - 0x18) = r1
       9:	18 01 00 00 73 5f 65 6e 00 00 00 00 74 65 72 5f	r1 = 0x5f7265746e655f73 ll
      11:	7b 1a e0 ff 00 00 00 00	*(u64 *)(r10 - 0x20) = r1
      12:	18 01 00 00 67 65 72 65 00 00 00 00 64 20 73 79	r1 = 0x7973206465726567 ll
      14:	7b 1a d8 ff 00 00 00 00	*(u64 *)(r10 - 0x28) = r1
      15:	18 01 00 00 42 50 46 20 00 00 00 00 74 72 69 67	r1 = 0x6769727420465042 ll
      17:	7b 1a d0 ff 00 00 00 00	*(u64 *)(r10 - 0x30) = r1
      18:	77 00 00 00 20 00 00 00	r0 >>= 0x20
      19:	bf a1 00 00 00 00 00 00	r1 = r10
      20:	07 01 00 00 d0 ff ff ff	r1 += -0x30
      21:	b7 02 00 00 2c 00 00 00	r2 = 0x2c
      22:	bf 03 00 00 00 00 00 00	r3 = r0
      23:	85 00 00 00 06 00 00 00	call 0x6
      24:	b7 00 00 00 00 00 00 00	r0 = 0x0
      25:	95 00 00 00 00 00 00 00	exit

There are instructions that load imm64 to the register, however in the code, it only supports imm64.

How to set up the environment

Hello, I'm curious to know how you configure the IDE while developing. Although I am able to run the project from the command line and fuzzing, I am having trouble reading the code and jumping to see the function definitions and references.

I don't know much about bazel, and I tried to set up the dev environment for several days. What's worse.. There is no tutorials about develop go program with bazel.

Hope to get a reply

Errors returned from ebpf apis should be exported for better testing/development practices

Currently in the codebase we do a lot of return fmt.Errorf(...) which is convenient but makes making sure that an error is a certain type a lot harder and creates fragile conditions for testing where we rely a lot on error strings.

Ideally we should have a list of errors somewhere that we export to users that can then go ahead and use those errors for comparisons, assertions, etc.

More debug information for the metrics server

Hi there!

I've had buzzer running for 16+ hours and my metrics server shows no coverage for verifier.c
I'm not sure if I'm not giving it the file parameter correctly. It would be good to know where I may need to troubleshoot

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.