mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-17 12:28:07 +00:00
add non-x86_64 architecture libfuzzer target support using qemu-user (#600)
This commit is contained in:
@ -42,6 +42,7 @@ BUILD = "0"
|
||||
class TemplateType(Enum):
|
||||
libfuzzer = "libfuzzer"
|
||||
libfuzzer_dotnet = "libfuzzer_dotnet"
|
||||
libfuzzer_qemu_user = "libfuzzer_qemu_user"
|
||||
afl = "afl"
|
||||
radamsa = "radamsa"
|
||||
|
||||
@ -57,6 +58,7 @@ class Integration(BaseModel):
|
||||
check_asan_log: Optional[bool] = Field(default=False)
|
||||
disable_check_debugger: Optional[bool] = Field(default=False)
|
||||
reboot_after_setup: Optional[bool] = Field(default=False)
|
||||
test_repro: Optional[bool] = Field(default=True)
|
||||
|
||||
|
||||
TARGETS: Dict[str, Integration] = {
|
||||
@ -84,6 +86,15 @@ TARGETS: Dict[str, Integration] = {
|
||||
use_setup=True,
|
||||
wait_for_files=[ContainerType.inputs, ContainerType.crashes],
|
||||
),
|
||||
"linux-libfuzzer-aarch64-crosscompile": Integration(
|
||||
template=TemplateType.libfuzzer_qemu_user,
|
||||
os=OS.linux,
|
||||
target_exe="fuzz.exe",
|
||||
inputs="inputs",
|
||||
use_setup=True,
|
||||
wait_for_files=[ContainerType.inputs, ContainerType.crashes],
|
||||
test_repro=False,
|
||||
),
|
||||
"linux-libfuzzer-rust": Integration(
|
||||
template=TemplateType.libfuzzer,
|
||||
os=OS.linux,
|
||||
@ -237,6 +248,17 @@ class TestOnefuzz:
|
||||
duration=1,
|
||||
vm_count=1,
|
||||
)
|
||||
elif config.template == TemplateType.libfuzzer_qemu_user:
|
||||
job = self.of.template.libfuzzer.qemu_user(
|
||||
self.project,
|
||||
target,
|
||||
BUILD,
|
||||
self.pools[config.os].name,
|
||||
inputs=inputs,
|
||||
target_exe=target_exe,
|
||||
duration=1,
|
||||
vm_count=1,
|
||||
)
|
||||
elif config.template == TemplateType.radamsa:
|
||||
job = self.of.template.radamsa.basic(
|
||||
self.project,
|
||||
@ -407,6 +429,10 @@ class TestOnefuzz:
|
||||
has_cdb = bool(which("cdb.exe"))
|
||||
has_gdb = bool(which("gdb"))
|
||||
for job_id in self.successful_jobs:
|
||||
if not TARGETS[self.target_jobs[job_id]].test_repro:
|
||||
self.logger.info("skipping repro for %s", self.target_jobs[job_id])
|
||||
continue
|
||||
|
||||
if self.job_os[job_id] == OS.linux and not has_gdb:
|
||||
self.logger.warning(
|
||||
"missing gdb in path, not launching repro: %s",
|
||||
|
3
src/integration-tests/libfuzzer-aarch64-crosscompile/.gitignore
vendored
Normal file
3
src/integration-tests/libfuzzer-aarch64-crosscompile/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
compiler-rt
|
||||
fuzz-libs
|
||||
fuzz.exe
|
@ -0,0 +1,31 @@
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
all: check
|
||||
|
||||
|
||||
fuzz-libs:
|
||||
sudo apt update
|
||||
sudo apt install -y qemu-user g++-aarch64-linux-gnu
|
||||
git clone https://github.com/llvm-mirror/compiler-rt
|
||||
|
||||
# last version that supports pc-guard instrumentation, required by GCC
|
||||
(cd compiler-rt; git checkout daa6759576548a2f3825faddaa6811cabbfb45eb)
|
||||
|
||||
# These *must* be built without ASAN
|
||||
mkdir -p fuzz-libs
|
||||
(cd fuzz-libs; aarch64-linux-gnu-g++ -c ../compiler-rt/lib/fuzzer/*.cpp)
|
||||
|
||||
fuzz.exe: fuzz-libs fuzz.c
|
||||
aarch64-linux-gnu-g++ -pthread -lasan -o fuzz.exe fuzz-libs/*.o fuzz.c -fsanitize=address -fsanitize-coverage=trace-pc
|
||||
|
||||
check: fuzz.exe
|
||||
ASAN_OPTIONS=:detect_leaks=0 qemu-aarch64 -L /usr/aarch64-linux-gnu ./fuzz.exe -runs=1
|
||||
|
||||
fuzz: check
|
||||
ASAN_OPTIONS=:detect_leaks=0 qemu-aarch64 -L /usr/aarch64-linux-gnu ./fuzz.exe
|
||||
|
||||
.PHONY: check clean fuzz
|
||||
|
||||
clean:
|
||||
rm -rf fuzz.exe fuzz-libs compiler-rt
|
64
src/integration-tests/libfuzzer-aarch64-crosscompile/fuzz.c
Normal file
64
src/integration-tests/libfuzzer-aarch64-crosscompile/fuzz.c
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const u_int8_t *data, size_t len) {
|
||||
int cnt = 0;
|
||||
|
||||
if (len < 4) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (data[0] == 'x') { cnt++; }
|
||||
if (data[1] == 'y') { cnt++; }
|
||||
if (data[2] == 'z') { cnt++; }
|
||||
|
||||
if (cnt >= 3) {
|
||||
switch (data[3]) {
|
||||
case '0': {
|
||||
// segv
|
||||
int *p = NULL; *p = 123;
|
||||
break;
|
||||
}
|
||||
case '1': {
|
||||
// stack-buffer-underflow
|
||||
int* p = &cnt - 32; for (int i = 0; i < 32; i++) { *(p + i) = 0; }
|
||||
break;
|
||||
}
|
||||
case '2': {
|
||||
// stack-buffer-overflow
|
||||
int* p = &cnt + 32; for (int i = 0; i < 32; i++) { *(p - i) = 0; }
|
||||
break;
|
||||
}
|
||||
case '3': {
|
||||
// bad-free
|
||||
int *p = &cnt; free(p);
|
||||
break;
|
||||
}
|
||||
case '4': {
|
||||
// double-free
|
||||
int* p = (int *) malloc(sizeof(int)); free(p); free(p);
|
||||
break;
|
||||
}
|
||||
case '5': {
|
||||
// heap-use-after-free
|
||||
int* p = (int *) malloc(sizeof(int)); free(p); *p = 123;
|
||||
break;
|
||||
}
|
||||
case '6': {
|
||||
// heap-buffer-overflow
|
||||
int* p = (int *) malloc(8 * sizeof(int)); for (int i = 0; i < 32; i++) { *(p + i) = 0; }
|
||||
break;
|
||||
}
|
||||
case '7': {
|
||||
// fpe
|
||||
int x = 0; int y = 123 / x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1 @@
|
||||
hi
|
@ -9,7 +9,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t len) {
|
||||
int cnt = 0;
|
||||
|
||||
if (len < 4) {
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (data[0] == 'x') { cnt++; }
|
||||
@ -40,17 +40,17 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t len) {
|
||||
}
|
||||
case '4': {
|
||||
// double-free
|
||||
int* p = malloc(sizeof(int)); free(p); free(p);
|
||||
int* p = (int *) malloc(sizeof(int)); free(p); free(p);
|
||||
break;
|
||||
}
|
||||
case '5': {
|
||||
// heap-use-after-free
|
||||
int* p = malloc(sizeof(int)); free(p); *p = 123;
|
||||
int* p = (int *) malloc(sizeof(int)); free(p); *p = 123;
|
||||
break;
|
||||
}
|
||||
case '6': {
|
||||
// heap-buffer-overflow
|
||||
int* p = malloc(8 * sizeof(int)); for (int i = 0; i < 32; i++) { *(p + i) = 0; }
|
||||
int* p = (int *) malloc(8 * sizeof(int)); for (int i = 0; i < 32; i++) { *(p + i) = 0; }
|
||||
break;
|
||||
}
|
||||
case '7': {
|
||||
@ -58,6 +58,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t len) {
|
||||
int x = 0; int y = 123 / x;
|
||||
break;
|
||||
}
|
||||
case '8': {
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user