Code Monkey home page Code Monkey logo

grebe's Introduction

GREBE

GREBE is an object-driven tool to identify Multiple Error Behavior of kernel bugs. GREBE consists of two components -- a static analysis tool to identify critical kernel objects of triggering the bug, and a fuzzing tool based Syzkaller to find its other error behavior. Refer to our paper for more details.

Usage scenario

You find a low-severity bug in kernel, and would like to know the true effect of the bug. Examples: CVE-2021-3715

You find a high-severity bug, and would like to know the bug's other memory corruption capability.

How to use fuzzer

Identify critical objects with the analyzer

see here

Patch kernel to support object coverage feedback

patch [target_kernel_dir]/kernel/kcov.c -p1 < ./kernel.patch

Build kernel with our gcc

export OBJ_FILE=[the_absolute_path_to_the_file_containing_critical_objects]
make CC=[path_to_our_gcc] -j`nproc`

Run the fuzzer

The fuzzer works like Syzkaller. It is noted that you should pass a POC to the syz-manager with -auxiliary flag.

Acknowledge

@INPROCEEDINGS{9833683,
author={Lin, Zhenpeng and Chen, Yueqi and Wu, Yuhang and Mu, Dongliang and Yu, Chensheng and Xing, Xinyu and Li, Kang},
booktitle={2022 IEEE Symposium on Security and Privacy (SP)},
title={GREBE: Unveiling Exploitation Potential for Linux Kernel Bugs},
year={2022},
pages={2078-2095},
doi={10.1109/SP46214.2022.9833683}
}

grebe's People

Contributors

markakd avatar whoismissing 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

Watchers

 avatar  avatar  avatar  avatar

grebe's Issues

Which compiler to build the kernel with? GCC, Clang, or both?

Greetings! I am trying to run GREBE following the documentations in this repository but I found the instructions of building the kernel seemed to conflict with each other.

In the main README:

Build kernel with our gcc

In the analyzer README:

build kernel as usual but make sure you are building with our custimized clang

So which one should I use? Or should I build the kernel twice using both GCC and Clang? It sounds like I should build with GCC for an actual runnable kernel, and build another one (unlikely to be runnable) with Clang from scratch for analysis only. Is it correct?

Some bitcode files are not generated when building the kernel with customized llvm.

I am trying to analyze this crash: https://syzkaller.appspot.com/bug?id=bdeea91ae259b3a42aa8ed8d8c91afd871eb5d80, and I compiled the clang with your patch. However, when I compiled the Linux kernel with command

make CC="/path/to/clang/" -j64

, I didn't get all .c files' bitcode file, and the missing bitcode files is needed. The error messages are as follows:

executing ~/GREBE/analyzer/build/lib/analyzer --crash-report=./case/report --call-graph=./case/report_cg.txt ./case/linux-bitcode/lib/list_debug.c.bc ./case/linux-bitcode/crypto/algapi.c.bc ./case/linux-bitcode/crypto/pcrypt.c.bc ./case/linux-bitcode/crypto/pcrypt.c.bc ./case/linux-bitcode/crypto/algboss.c.bc ./case/linux-bitcode/kernel/kthread.c.bc ./case/linux-bitcode/arch/x86/entry/entry_64.S.bc 

Total 7 file(s)
/home/ws/GREBE/analyzer/build/lib/analyzer: error loading file './case/linux-bitcode/lib/list_debug.c.bc'
/home/ws/GREBE/analyzer/build/lib/analyzer: error loading file './case/linux-bitcode/crypto/pcrypt.c.bc'
/home/ws/GREBE/analyzer/build/lib/analyzer: error loading file './case/linux-bitcode/crypto/pcrypt.c.bc'
/home/ws/GREBE/analyzer/build/lib/analyzer: error loading file './case/linux-bitcode/arch/x86/entry/entry_64.S.bc'
inserting __list_del_entry_valid __list_del_entry
inserting __list_del_entry list_del
inserting list_del crypto_drop_spawn
inserting crypto_drop_spawn crypto_drop_aead
inserting crypto_drop_aead pcrypt_create_aead
inserting pcrypt_create_aead pcrypt_create
inserting pcrypt_create cryptomgr_probe
inserting cryptomgr_probe kthread
inserting kthread ret_from_fork
Here is the crash location __list_del_entry_valid lib/list_debug.c:51 explicit checking? 1
analyzer: /home/ws/GREBE/analyzer/src/lib/CrashAnalyzer.cc:248: void CrashAnalyzer::dump(llvm::StringRef): Assertion `Ctx->TaintSrc.size() > 0 || Ctx->TmpTaintSrc.size() > 0' failed.
 #0 0x00000000005d57ff llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/home/ws/GREBE/analyzer/build/lib/analyzer+0x5d57ff)
 #1 0x00000000005d3a82 llvm::sys::RunSignalHandlers() (/home/ws/GREBE/analyzer/build/lib/analyzer+0x5d3a82)
 #2 0x00000000005d6075 SignalHandler(int) (/home/ws/GREBE/analyzer/build/lib/analyzer+0x5d6075)
 #3 0x00007ff1fd922420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #4 0x00007ff1fd41100b raise /build/glibc-SzIz7B/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #5 0x00007ff1fd3f0859 abort /build/glibc-SzIz7B/glibc-2.31/stdlib/abort.c:81:7
 #6 0x00007ff1fd3f0729 get_sysdep_segment_value /build/glibc-SzIz7B/glibc-2.31/intl/loadmsgcat.c:509:8
 #7 0x00007ff1fd3f0729 _nl_load_domain /build/glibc-SzIz7B/glibc-2.31/intl/loadmsgcat.c:970:34
 #8 0x00007ff1fd401fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #9 0x0000000000563d83 CrashAnalyzer::dump(llvm::StringRef) /home/ws/GREBE/analyzer/src/lib/CrashAnalyzer.cc:0:5
#10 0x0000000000563b78 CrashAnalyzer::dump() /home/ws/GREBE/analyzer/src/lib/CrashAnalyzer.cc:233:1
#11 0x000000000052e50a main /home/ws/GREBE/analyzer/src/lib/KAMain.cc:269:16
#12 0x00007ff1fd3f2083 __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:342:3
#13 0x000000000052c95e _start (/home/ws/GREBE/analyzer/build/lib/analyzer+0x52c95e)
Stack dump:
0.	Program arguments: /home/ws/GREBE/analyzer/build/lib/analyzer --crash-report=./case/report --call-graph=./case/report_cg.txt ./case/linux-bitcode/lib/list_debug.c.bc ./case/linux-bitcode/crypto/algapi.c.bc ./case/linux-bitcode/crypto/pcrypt.c.bc ./case/linux-bitcode/crypto/pcrypt.c.bc ./case/linux-bitcode/crypto/algboss.c.bc ./case/linux-bitcode/kernel/kthread.c.bc ./case/linux-bitcode/arch/x86/entry/entry_64.S.bc 
Aborted (core dumped)
Traceback (most recent call last):
  File "run_analyze.py", line 68, in <module>
    run_case(sys.argv[1])
  File "run_analyze.py", line 65, in run_case
    shutil.copyfile("/tmp/ca_result", case_path+"/sts.txt")
  File "/usr/lib/python3.8/shutil.py", line 264, in copyfile
    with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst:
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/ca_result'

So is my kernel compile command wrong?

Crash info "WARNING in cgroup_apply_control_disable" appear repeatedly in each bug

Hi, I get this crash info WARNING in cgroup_apply_control_disable repeatedly while fuzzing the bug, and part of the console info is as follows:

2023/09/05 15:16:24 vm-0: crash: WARNING in cgroup_apply_control_disable
2023/09/05 15:16:28 vm-1: crash: WARNING in cgroup_apply_control_disable
2023/09/05 15:16:30 VMs 1, executed 114, corpus cover 0, corpus signal 0, object signal 0, max signal 0, crashes 18, repro 0
2023/09/05 15:16:39 vm-2: crash: WARNING in cgroup_apply_control_disable
2023/09/05 15:16:40 VMs 1, executed 121, corpus cover 0, corpus signal 0, object signal 0, max signal 0, crashes 19, repro 0
2023/09/05 15:16:47 vm-3: crash: WARNING in cgroup_apply_control_disable

I have changed the SYZ bug reports (d2c64e2/09fc5ec/8eceaff), and also the Ubuntu version (16.04/20.04), but it doesn't work, I still get the same crash info.

Maybe there's something wrong with the kernel configuration. I configured the kernel of each bug report with the following steps(take the first case in your Google doc, d2c64e2 as an example:

  1. Get the kernel config in the first line of Crashes table below the report page.
  2. Download the corresponding Linux kernel version shown in the config. (In this case, the kernel version is 5.7.0)
  3. Unzip the kernel file, and patch it with the command patch [target_kernel_dir]/kernel/kcov.c -p1 < ./kernel.patch.
  4. Set the environment variable with export OBJ_FILE=[the_absolute_path_to_the_file_containing_critical_objects].
  5. Generate the .config file with make defconfig, and fully replace it with the SYZ bug report kernel config. After that, edit some configs as follows:
# Coverage collection.
CONFIG_KCOV=y

# Debug info for symbolization.
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_DWARF4=y

# Memory bug detector
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y

# Required for Debian Stretch
CONFIG_CONFIGFS_FS=y
CONFIG_SECURITYFS=y

CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="net.ifnames=0"

These configs are reqired in the syzkaller setup.
6. Save the config with make olddefconfig, and compile the kernel with your costomized gcc make CC=[path_to_our_gcc] -j `nproc` .
7. Run the fuzzer with ./bin/syz-manager -config=config -auxiliary=./crash_report/1_poc.txt. The config and poc file are as follows:
config file:

{
	"target": "linux/amd64",
	"http": "127.0.0.1:56741",
	"workdir": "/opt/GREBE/GREBE/fuzzer/workdir",
	"kernel_obj": "/opt/GREBE/linux-kernel/linux-5.7",
	"image": "/opt/GREBE/image/bullseye.img",
	"sshkey": "/opt/GREBE/image/bullseye.id_rsa",
	"syzkaller": "/opt/GREBE/GREBE/fuzzer",
	"procs": 8,
	"type": "qemu",
	"reproduce": false,
	"vm": {
		"count": 4,
		"kernel": "/opt/GREBE/linux-kernel/linux-5.7/arch/x86/boot/bzImage",
		"snapshot": true,
		"cpu": 2,
		"mem": 2048
	}
}

poc file: (Syz repro column of the same crash line)

# https://syzkaller.appspot.com/bug?id=d2c64e2d7c308cce1b51fd51addd4284cd825792
# See https://goo.gl/kgGztJ for information about syzkaller reproducers.
#{"procs":1,"sandbox":"none","fault_call":-1,"close_fds":true}
r0 = socket$pppl2tp(0x18, 0x1, 0x1)
r1 = socket$inet6(0xa, 0x80002, 0x0)
setsockopt$sock_int(r1, 0x1, 0xf, &(0x7f0000000180)=0xb, 0x4)
bind$inet6(r1, &(0x7f0000f5dfe4)={0xa, 0x4e20, 0x0, @empty}, 0x1c)
connect$pppl2tp(r0, &(0x7f00000001c0)=@pppol2tpv3in6={0x18, 0x1, {0x0, r1, 0x1, 0x0, 0x1, 0x0, {0xa, 0x4e20, 0x7, @ipv4={[], [], @dev={0xac, 0x14, 0x14, 0x12}}, 0x3ff}}}, 0x3a)

Could you please help me with this problem? Or even some hints will be helpful, thanks!

analyzer failed

/home/GREBE/analyzer/build/lib/analyzer --crash-report=./report --call-graph=./report_cg.txt ./linux-bitcode/lib/dump_stack.c.bc ./linux-bitcode/lib/dump_stack.c.bc ./linux-bitcode/mm/kasan/report.c.bc ./linux-bitcode/mm/kasan/report.c.bc ./linux-bitcode/mm/kasan/report.c.bc ./linux-bitcode/mm/kasan/generic.c.bc ./linux-bitcode/mm/kasan/generic.c.bc ./linux-bitcode/mm/kasan/common.c.bc ./linux-bitcode/net/netfilter/x_tables.c.bc ./linux-bitcode/net/ipv6/netfilter/ip6_tables.c.bc ./linux-bitcode/net/ipv6/netfilter/ip6_tables.c.bc ./linux-bitcode/net/ipv6/netfilter/ip6_tables.c.bc ./linux-bitcode/net/ipv6/netfilter/ip6_tables.c.bc ./linux-bitcode/net/netfilter/nf_sockopt.c.bc ./linux-bitcode/net/ipv6/ipv6_sockglue.c.bc ./linux-bitcode/net/ipv6/udp.c.bc ./linux-bitcode/net/socket.c.bc ./linux-bitcode/net/socket.c.bc ./linux-bitcode/net/socket.c.bc ./linux-bitcode/net/socket.c.bc ./linux-bitcode/arch/x86/entry/common.c.bc ./linux-bitcode/arch/x86/entry/common.c.bc ./linux-bitcode/arch/x86/entry/common.c.bc
Total 23 file(s)
inserting __dump_stack dump_stack
inserting dump_stack print_address_description
inserting print_address_description __kasan_report
inserting __kasan_report kasan_report
inserting kasan_report check_memory_region_inline
inserting check_memory_region_inline check_memory_region
inserting check_memory_region memset
inserting memset memset
inserting memset xt_compat_target_from_user
inserting xt_compat_target_from_user compat_copy_entry_from_user
inserting compat_copy_entry_from_user translate_compat_table
inserting translate_compat_table compat_do_replace
inserting compat_do_replace do_ip6t_set_ctl
inserting do_ip6t_set_ctl nf_setsockopt
inserting nf_setsockopt ipv6_setsockopt
inserting ipv6_setsockopt udpv6_setsockopt
inserting udpv6_setsockopt __sys_setsockopt
inserting __sys_setsockopt __do_sys_setsockopt
inserting __do_sys_setsockopt __se_sys_setsockopt
inserting __se_sys_setsockopt __ia32_sys_setsockopt
inserting __ia32_sys_setsockopt do_syscall_32_irqs_on
inserting do_syscall_32_irqs_on __do_fast_syscall_32
inserting __do_fast_syscall_32 do_fast_syscall_32
Here is the crash location memset mm/kasan/common.c:84 explicit checking? 0
analyzer: /home/GREBE/analyzer/src/lib/CrashAnalyzer.cc:248: void CrashAnalyzer::dump(llvm::StringRef): Assertion `Ctx->TaintSrc.size() > 0 || Ctx->TmpTaintSrc.size() > 0' failed.
#0 0x00000000005cf20a llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/home/GREBE/analyzer/build/lib/analyzer+0x5cf20a)
#1 0x00000000005ccdf4 llvm::sys::RunSignalHandlers() (/home/GREBE/analyzer/build/lib/analyzer+0x5ccdf4)
#2 0x00000000005ccf43 SignalHandler(int) (/home/GREBE/analyzer/build/lib/analyzer+0x5ccf43)
#3 0x00007f68b1d98980 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x12980)
#4 0x00007f68b1094e87 raise /build/glibc-CVJwZb/glibc-2.27/signal/../sysdeps/unix/sysv/linux/raise.c:51:0
#5 0x00007f68b10967f1 abort /build/glibc-CVJwZb/glibc-2.27/stdlib/abort.c:81:0
#6 0x00007f68b10863fa __assert_fail_base /build/glibc-CVJwZb/glibc-2.27/assert/assert.c:89:0
#7 0x00007f68b1086472 (/lib/x86_64-linux-gnu/libc.so.6+0x30472)
#8 0x000000000055b033 CrashAnalyzer::dump(llvm::StringRef) /home/GREBE/analyzer/src/lib/CrashAnalyzer.cc:0:5
#9 0x000000000055ae28 CrashAnalyzer::dump() /home/GREBE/analyzer/src/lib/CrashAnalyzer.cc:233:1
#10 0x0000000000524afa main /home/GREBE/analyzer/src/lib/KAMain.cc:269:16
#11 0x00007f68b1077c87 __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:344:0
#12 0x0000000000522f4a _start (/home/GREBE/analyzer/build/lib/analyzer+0x522f4a)
Stack dump:
0. Program arguments: /home/GREBE/analyzer/build/lib/analyzer --crash-report=./report --call-graph=./report_cg.txt ./linux-bitcode/lib/dump_stack.c.bc ./linux-bitcode/lib/dump_stack.c.bc ./linux-bitcode/mm/kasan/report.c.bc ./linux-bitcode/mm/kasan/report.c.bc ./linux-bitcode/mm/kasan/report.c.bc ./linux-bitcode/mm/kasan/generic.c.bc ./linux-bitcode/mm/kasan/generic.c.bc ./linux-bitcode/mm/kasan/common.c.bc ./linux-bitcode/net/netfilter/x_tables.c.bc ./linux-bitcode/net/ipv6/netfilter/ip6_tables.c.bc ./linux-bitcode/net/ipv6/netfilter/ip6_tables.c.bc ./linux-bitcode/net/ipv6/netfilter/ip6_tables.c.bc ./linux-bitcode/net/ipv6/netfilter/ip6_tables.c.bc ./linux-bitcode/net/netfilter/nf_sockopt.c.bc ./linux-bitcode/net/ipv6/ipv6_sockglue.c.bc ./linux-bitcode/net/ipv6/udp.c.bc ./linux-bitcode/net/socket.c.bc ./linux-bitcode/net/socket.c.bc ./linux-bitcode/net/socket.c.bc ./linux-bitcode/net/socket.c.bc ./linux-bitcode/arch/x86/entry/common.c.bc ./linux-bitcode/arch/x86/entry/common.c.bc ./linux-bitcode/arch/x86/entry/common.c.bc
Aborted (core dumped)

Empty WorkSeed Error

Hello,
After all the necessary installation steps, I start to run the grebe fuzzer. However, from the debug log, I encounter an error with the hint "panic: Empty WorkSeed!". As a result, the fuzzing processes are always be interrupted and no executions from the debug output. I worked through the source codes and found the length of the variable r.ProgSeed is zero and the branch with the hint "Received seed prog" did not have been executed. Further and farthest, I found the code "r := &rpctype.ConnectRes{}" do return the empty to r. So the panic is correct? I'm confused with this part. Could you please help to identify the problem I met?
Thanks for your help.

Question about how to pass POC to syz-manager with the -auxiliary flag

Thank you very much for open sourcing the code, in the process of reproducing the experiment, I got stuck in the operation of transferring the POC to syz-manager.
I tried the command:
syz-manager -config=my.config -auxiliary=path_to_poc
and adding configuration items to my.cfg configuration file. Both of the above do not run syz-manager correctly, and I would like to ask how this step is achieved.
Also the source code related to seed mutation optimization during fuzzy testing could you explain where it is implemented?

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.