mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-15 11:28:09 +00:00
Move integration test artifacts into primary source tree (#336)
This commit is contained in:
73
.github/workflows/ci.yml
vendored
73
.github/workflows/ci.yml
vendored
@ -312,3 +312,76 @@ jobs:
|
||||
with:
|
||||
name: release-artifacts
|
||||
path: release-artifacts
|
||||
build-integration-tests-linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: |
|
||||
set -ex
|
||||
cd src/integration-tests
|
||||
mkdir -p artifacts
|
||||
cp integration-test.py artifacts/
|
||||
|
||||
mkdir -p artifacts/linux-libfuzzer
|
||||
(cd libfuzzer ; make )
|
||||
cp -r libfuzzer/fuzz.exe libfuzzer/seeds artifacts/linux-libfuzzer
|
||||
|
||||
mkdir -p artifacts/linux-trivial-crash
|
||||
(cd trivial-crash ; make )
|
||||
cp -r trivial-crash/fuzz.exe trivial-crash/seeds artifacts/linux-trivial-crash
|
||||
|
||||
mkdir -p artifacts/linux-trivial-crash-asan
|
||||
(cd trivial-crash ; make clean; make CFLAGS='-fsanitize=address -fno-omit-frame-pointer')
|
||||
cp -r trivial-crash/fuzz.exe trivial-crash/seeds artifacts/linux-trivial-crash-asan
|
||||
|
||||
mkdir -p artifacts/linux-libfuzzer-rust
|
||||
(cd libfuzzer-rust ; make )
|
||||
cp -r libfuzzer-rust/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1 artifacts/linux-libfuzzer-rust
|
||||
|
||||
# AFL v2.75b
|
||||
mkdir -p artifacts/linux-trivial-crash-afl
|
||||
git clone https://github.com/google/AFL
|
||||
(cd AFL; git checkout 82b5e359463238d790cadbe2dd494d6a4928bff3; make afl-gcc afl-fuzz afl-as)
|
||||
export AFL_CC_PATH=$PWD/AFL/afl-clang
|
||||
(cd trivial-crash ; make clean; make CC=$AFL_CC_PATH)
|
||||
cp -r trivial-crash/fuzz.exe trivial-crash/seeds artifacts/linux-trivial-crash-afl
|
||||
- uses: actions/upload-artifact@v2.1.4
|
||||
with:
|
||||
name: integration-test-artifacts
|
||||
path: src/integration-tests/artifacts
|
||||
build-integration-tests-windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: |
|
||||
Set-ExecutionPolicy Bypass -Scope Process -Force
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
Invoke-Expression (Invoke-RestMethod 'https://chocolatey.org/install.ps1')
|
||||
choco install llvm
|
||||
choco install make
|
||||
$env:Path += ";C:\Program Files\LLVM\bin;C:\ProgramData\chocolatey\bin"
|
||||
|
||||
cd src/integration-tests
|
||||
|
||||
mkdir artifacts/windows-libfuzzer
|
||||
cd libfuzzer
|
||||
make
|
||||
cp fuzz.exe,fuzz.pdb,seeds ../artifacts/windows-libfuzzer -Recurse
|
||||
cd ../
|
||||
|
||||
mkdir artifacts/windows-trivial-crash
|
||||
cd trivial-crash
|
||||
make
|
||||
cp fuzz.exe,fuzz.pdb,seeds ../artifacts/windows-trivial-crash -Recurse
|
||||
cd ../
|
||||
|
||||
mkdir artifacts/windows-trivial-crash-asan
|
||||
cd trivial-crash
|
||||
make clean
|
||||
make CFLAGS='-fsanitize=address -fno-omit-frame-pointer'
|
||||
cp fuzz.exe,fuzz.pdb,seeds ../artifacts/windows-trivial-crash-asan -Recurse
|
||||
shell: powershell
|
||||
- uses: actions/upload-artifact@v2.1.4
|
||||
with:
|
||||
name: integration-test-artifacts
|
||||
path: src/integration-tests/artifacts
|
||||
|
9
src/integration-tests/libfuzzer-rust/Cargo.toml
Normal file
9
src/integration-tests/libfuzzer-rust/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "rust_fuzz_example"
|
||||
version = "0.1.0"
|
||||
license = "MIT"
|
||||
authors = ["<fuzzing@microsoft.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2.79"
|
10
src/integration-tests/libfuzzer-rust/Makefile
Normal file
10
src/integration-tests/libfuzzer-rust/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
.PHONY: all clean
|
||||
|
||||
all:
|
||||
rustup install nightly
|
||||
cargo install cargo-fuzz
|
||||
cargo +nightly fuzz build --release
|
||||
|
||||
clean:
|
||||
cargo clean
|
||||
(cd fuzz; cargo clean)
|
22
src/integration-tests/libfuzzer-rust/README.md
Normal file
22
src/integration-tests/libfuzzer-rust/README.md
Normal file
@ -0,0 +1,22 @@
|
||||
# Fuzzing Rust in OneFuzz
|
||||
|
||||
OneFuzz can orchastrate fuzzing of Rust using
|
||||
[cargo-fuzz](https://crates.io/crates/cargo-fuzz) to build libfuzzer based
|
||||
fuzzing targets.
|
||||
|
||||
Included in this directory is a simple example to demonstrate rust based
|
||||
fuzzing. For more examples, check out the libfuzzer examples in the [rust
|
||||
fuzzing trophy case](https://github.com/rust-fuzz/trophy-case).
|
||||
|
||||
## Example command
|
||||
|
||||
```bash
|
||||
# ensure the latest cargo-fuzz is installed
|
||||
cargo install cargo-fuzz --force
|
||||
# build your fuzzing targets
|
||||
cargo +nightly fuzz build --release
|
||||
# Launch a fuzz job for each of the targets provided by cargo-fuzz
|
||||
for target in $(cargo fuzz list); do
|
||||
onefuzz template libfuzzer basic $PROJECT_NAME $target $BUILD_NUMBER $POOL_NAME --target_exe ./fuzz/target/x86_64-unknown-linux-gnu/release/$target --inputs ./fuzz/corpus/$target
|
||||
done
|
||||
```
|
3
src/integration-tests/libfuzzer-rust/fuzz/.gitignore
vendored
Normal file
3
src/integration-tests/libfuzzer-rust/fuzz/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
target
|
||||
corpus
|
||||
artifacts
|
25
src/integration-tests/libfuzzer-rust/fuzz/Cargo.toml
Normal file
25
src/integration-tests/libfuzzer-rust/fuzz/Cargo.toml
Normal file
@ -0,0 +1,25 @@
|
||||
[package]
|
||||
name = "rust-fuzz"
|
||||
version = "0.0.0"
|
||||
authors = ["Automatically generated"]
|
||||
publish = false
|
||||
edition = "2018"
|
||||
|
||||
[package.metadata]
|
||||
cargo-fuzz = true
|
||||
|
||||
[dependencies]
|
||||
libfuzzer-sys = "0.3"
|
||||
|
||||
[dependencies.rust_fuzz_example]
|
||||
path = ".."
|
||||
|
||||
# Prevent this from interfering with workspaces
|
||||
[workspace]
|
||||
members = ["."]
|
||||
|
||||
[[bin]]
|
||||
name = "fuzz_target_1"
|
||||
path = "fuzz_targets/fuzz_target_1.rs"
|
||||
test = false
|
||||
doc = false
|
@ -0,0 +1,7 @@
|
||||
#![no_main]
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
use rust_fuzz_example;
|
||||
|
||||
fuzz_target!(|data: &[u8]| {
|
||||
rust_fuzz_example::check(data);
|
||||
});
|
34
src/integration-tests/libfuzzer-rust/src/lib.rs
Normal file
34
src/integration-tests/libfuzzer-rust/src/lib.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
extern crate libc;
|
||||
|
||||
pub fn check(data: &[u8]) -> bool {
|
||||
if data.len() < 4 {
|
||||
return false;
|
||||
}
|
||||
|
||||
if data[0] != 0x41 {
|
||||
return false;
|
||||
}
|
||||
|
||||
if data[1] != 0x42 {
|
||||
return false;
|
||||
}
|
||||
|
||||
if data[2] != 0x43 {
|
||||
return false;
|
||||
}
|
||||
|
||||
match data[3] {
|
||||
// OOB access
|
||||
4 => data[100000] == 0xFF,
|
||||
// null ptr
|
||||
5 => unsafe {
|
||||
let ptr: *mut u8 = 0 as *mut u8;
|
||||
*ptr = 10;
|
||||
true
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
16
src/integration-tests/libfuzzer/Makefile
Normal file
16
src/integration-tests/libfuzzer/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
CC=clang
|
||||
|
||||
CFLAGS=-g3 -fsanitize=fuzzer -fsanitize=address
|
||||
|
||||
all: fuzz.exe
|
||||
|
||||
fuzz.exe: simple.c
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
|
||||
test: fuzz.exe
|
||||
./fuzz.exe -runs=100 seeds
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -f fuzz.exe
|
1
src/integration-tests/libfuzzer/seeds/good.txt
Normal file
1
src/integration-tests/libfuzzer/seeds/good.txt
Normal file
@ -0,0 +1 @@
|
||||
good
|
65
src/integration-tests/libfuzzer/simple.c
Normal file
65
src/integration-tests/libfuzzer/simple.c
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t len) {
|
||||
int cnt = 0;
|
||||
|
||||
if (len < 4) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
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 = malloc(sizeof(int)); free(p); free(p);
|
||||
break;
|
||||
}
|
||||
case '5': {
|
||||
// heap-use-after-free
|
||||
int* p = 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; }
|
||||
break;
|
||||
}
|
||||
case '7': {
|
||||
// fpe
|
||||
int x = 0; int y = 123 / x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
19
src/integration-tests/trivial-crash/Makefile
Executable file
19
src/integration-tests/trivial-crash/Makefile
Executable file
@ -0,0 +1,19 @@
|
||||
ifeq ($(OS),Windows_NT)
|
||||
CLEANCMD=del fuzz.exe, fuzz.exp, fuzz.lib, fuzz.pdb, fuzz-afl.exe, afl-llvm-rt.o.o, fuzz.o, main.o
|
||||
else
|
||||
CLEANCMD=rm -rf fuzz.exe fuzz.exp fuzz.lib fuzz.pdb fuzz-afl.exe afl-llvm-rt.o.o fuzz.o main.o
|
||||
endif
|
||||
|
||||
CC=clang
|
||||
OBJS=fuzz.c
|
||||
CFLAGS=-O3 -funroll-loops -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign
|
||||
|
||||
all: fuzz.exe
|
||||
|
||||
fuzz.exe: $(OBJS)
|
||||
$(CC) -g3 $(CFLAGS) $(OBJS) -o $@
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
$(CLEANCMD)
|
83
src/integration-tests/trivial-crash/fuzz.c
Normal file
83
src/integration-tests/trivial-crash/fuzz.c
Normal file
@ -0,0 +1,83 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN64
|
||||
#include <io.h>
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#define STDIN_FILENO _fileno(stdin)
|
||||
#define read _read
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define SIZE 8192
|
||||
#define BUF_SIZE 32
|
||||
|
||||
int check(const char *data, size_t len)
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
memset(buf, 0, BUF_SIZE);
|
||||
strncpy(buf, data, len); // BUG - This incorrectly uses length of src, not dst
|
||||
|
||||
// do something to ensure this isn't optimized away
|
||||
int buflen = strlen(buf);
|
||||
for (int i = 0; i <= ((buflen % 2 == 1) ? buflen - 1 : buflen) / 2; i++)
|
||||
{
|
||||
if (buf[i] != buf[buflen - 1 - i])
|
||||
{
|
||||
printf("not palindrome\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int from_stdin()
|
||||
{
|
||||
char input[SIZE] = {0};
|
||||
int size = read(STDIN_FILENO, input, SIZE);
|
||||
return check(input, size);
|
||||
}
|
||||
|
||||
int from_file(char *filename)
|
||||
{
|
||||
FILE *infile;
|
||||
char *buffer;
|
||||
long length;
|
||||
int result;
|
||||
|
||||
infile = fopen(filename, "r");
|
||||
|
||||
if (infile == NULL)
|
||||
return 1;
|
||||
|
||||
fseek(infile, 0L, SEEK_END);
|
||||
length = ftell(infile);
|
||||
|
||||
fseek(infile, 0L, SEEK_SET);
|
||||
buffer = calloc(length, sizeof(char));
|
||||
if (buffer == NULL)
|
||||
return 1;
|
||||
|
||||
length = fread(buffer, sizeof(char), length, infile);
|
||||
fclose(infile);
|
||||
|
||||
result = check(buffer, length);
|
||||
free(buffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
return from_stdin();
|
||||
}
|
||||
else if (argc > 1)
|
||||
{
|
||||
return from_file(argv[1]);
|
||||
}
|
||||
}
|
1
src/integration-tests/trivial-crash/seeds/fail.txt
Normal file
1
src/integration-tests/trivial-crash/seeds/fail.txt
Normal file
@ -0,0 +1 @@
|
||||
hello
|
1
src/integration-tests/trivial-crash/seeds/pass.txt
Normal file
1
src/integration-tests/trivial-crash/seeds/pass.txt
Normal file
@ -0,0 +1 @@
|
||||
racecar
|
Reference in New Issue
Block a user