mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-15 03:18:07 +00:00
libfuzzer library integration tests (#681)
This commit is contained in:
14
.github/workflows/ci.yml
vendored
14
.github/workflows/ci.yml
vendored
@ -366,6 +366,14 @@ jobs:
|
||||
(cd libfuzzer-dotnet; make)
|
||||
cp -r libfuzzer-dotnet/my-fuzzer libfuzzer-dotnet/inputs artifacts/linux-libfuzzer-dotnet/
|
||||
|
||||
mkdir -p artifacts/linux-libfuzzer-dlopen
|
||||
(cd libfuzzer-dlopen; make)
|
||||
cp -r libfuzzer-dlopen/{fuzz.exe,*.so,seeds} artifacts/linux-libfuzzer-dlopen/
|
||||
|
||||
mkdir -p artifacts/linux-libfuzzer-linked-library
|
||||
(cd libfuzzer-linked-library; make)
|
||||
cp -r libfuzzer-linked-library/{fuzz.exe,*.so,seeds} artifacts/linux-libfuzzer-linked-library/
|
||||
|
||||
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
|
||||
@ -417,6 +425,12 @@ jobs:
|
||||
cp fuzz.exe,fuzz.pdb,seeds ../artifacts/windows-trivial-crash -Recurse
|
||||
cd ../
|
||||
|
||||
mkdir artifacts/windows-libfuzzer-linked-library
|
||||
cd libfuzzer-linked-library
|
||||
make -f Makefile.windows
|
||||
cp fuzz.exe,fuzz.pdb,bad1.dll,bad1.pdb,bad2.dll,bad2.pdb,seeds ../artifacts/windows-libfuzzer-linked-library -Recurse
|
||||
cd ../
|
||||
|
||||
mkdir artifacts/windows-trivial-crash-asan
|
||||
cd trivial-crash
|
||||
make clean
|
||||
|
@ -88,6 +88,32 @@ TARGETS: Dict[str, Integration] = {
|
||||
},
|
||||
reboot_after_setup=True,
|
||||
),
|
||||
"linux-libfuzzer-dlopen": Integration(
|
||||
template=TemplateType.libfuzzer,
|
||||
os=OS.linux,
|
||||
target_exe="fuzz.exe",
|
||||
inputs="seeds",
|
||||
wait_for_files={
|
||||
ContainerType.unique_reports: 1,
|
||||
ContainerType.coverage: 1,
|
||||
ContainerType.inputs: 2,
|
||||
},
|
||||
reboot_after_setup=True,
|
||||
use_setup=True,
|
||||
),
|
||||
"linux-libfuzzer-linked-library": Integration(
|
||||
template=TemplateType.libfuzzer,
|
||||
os=OS.linux,
|
||||
target_exe="fuzz.exe",
|
||||
inputs="seeds",
|
||||
wait_for_files={
|
||||
ContainerType.unique_reports: 1,
|
||||
ContainerType.coverage: 1,
|
||||
ContainerType.inputs: 2,
|
||||
},
|
||||
reboot_after_setup=True,
|
||||
use_setup=True,
|
||||
),
|
||||
"linux-libfuzzer-dotnet": Integration(
|
||||
template=TemplateType.libfuzzer_dotnet,
|
||||
os=OS.linux,
|
||||
@ -140,6 +166,18 @@ TARGETS: Dict[str, Integration] = {
|
||||
ContainerType.coverage: 1,
|
||||
},
|
||||
),
|
||||
"windows-libfuzzer-linked-library": Integration(
|
||||
template=TemplateType.libfuzzer,
|
||||
os=OS.windows,
|
||||
target_exe="fuzz.exe",
|
||||
inputs="seeds",
|
||||
wait_for_files={
|
||||
ContainerType.inputs: 2,
|
||||
ContainerType.unique_reports: 1,
|
||||
ContainerType.coverage: 1,
|
||||
},
|
||||
use_setup=True,
|
||||
),
|
||||
"windows-trivial-crash": Integration(
|
||||
template=TemplateType.radamsa,
|
||||
os=OS.windows,
|
||||
|
18
src/integration-tests/libfuzzer-dlopen/Makefile
Normal file
18
src/integration-tests/libfuzzer-dlopen/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
CC=clang
|
||||
CFLAGS=-fsanitize=address,fuzzer -fPIC -O0 -ggdb3
|
||||
|
||||
.PHONY: all clean test
|
||||
|
||||
all: libbad.so fuzz.exe
|
||||
|
||||
fuzz.exe: main.o
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
libbad.so: bad.o
|
||||
$(CC) -shared -o $@ $<
|
||||
|
||||
test: all
|
||||
LD_LIBRARY_PATH=. ./fuzz.exe
|
||||
|
||||
clean:
|
||||
rm -rf fuzz.exe *.o *.so crash-*
|
64
src/integration-tests/libfuzzer-dlopen/bad.c
Normal file
64
src/integration-tests/libfuzzer-dlopen/bad.c
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int func(const uint8_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 = 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;
|
||||
}
|
9
src/integration-tests/libfuzzer-dlopen/bad.h
Normal file
9
src/integration-tests/libfuzzer-dlopen/bad.h
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifndef BAD_H
|
||||
#define BAD_H
|
||||
|
||||
int func(const uint8_t *data, size_t len);
|
||||
|
||||
#endif
|
39
src/integration-tests/libfuzzer-dlopen/main.c
Normal file
39
src/integration-tests/libfuzzer-dlopen/main.c
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include <assert.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int (*fuzz_func)(const uint8_t *data, size_t size);
|
||||
|
||||
int LLVMFuzzerInitialize(int *argc, char ***argv)
|
||||
{
|
||||
printf("initialize\n");
|
||||
void *handle;
|
||||
int (*b)(void);
|
||||
char *error;
|
||||
|
||||
handle = dlopen("libbad.so", RTLD_LAZY);
|
||||
if (!handle)
|
||||
{
|
||||
printf("can't open %s", dlerror());
|
||||
return 1;
|
||||
}
|
||||
fuzz_func = (int (*)(const uint8_t *data, size_t size))dlsym(handle, "func");
|
||||
error = dlerror();
|
||||
if (error != NULL)
|
||||
{
|
||||
printf("%s\n", error);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
assert(fuzz_func != NULL);
|
||||
return fuzz_func(data, size);
|
||||
}
|
1
src/integration-tests/libfuzzer-dlopen/seeds/good.txt
Normal file
1
src/integration-tests/libfuzzer-dlopen/seeds/good.txt
Normal file
@ -0,0 +1 @@
|
||||
good
|
22
src/integration-tests/libfuzzer-linked-library/Makefile
Normal file
22
src/integration-tests/libfuzzer-linked-library/Makefile
Normal file
@ -0,0 +1,22 @@
|
||||
CC=clang
|
||||
|
||||
.PHONY: all clean test
|
||||
|
||||
all: fuzz.exe
|
||||
|
||||
CFLAGS=-fsanitize=address,fuzzer -fPIC -O0 -ggdb3
|
||||
|
||||
fuzz.exe: main.o libbad1.so libbad2.so
|
||||
$(CC) $(CFLAGS) -o $@ $< -lbad1 -lbad2 -L.
|
||||
|
||||
libbad1.so: bad1.o
|
||||
$(CC) -fsanitize=address -shared -o $@ $<
|
||||
|
||||
libbad2.so: bad2.o
|
||||
$(CC) -fsanitize=address -shared -o $@ $<
|
||||
|
||||
test: all
|
||||
LD_LIBRARY_PATH=. ./fuzz.exe
|
||||
|
||||
clean:
|
||||
rm -rf fuzz.exe *.o *.so *.dll crash-* *.lib *.exp *.pdb
|
@ -0,0 +1,23 @@
|
||||
CC=clang
|
||||
|
||||
.PHONY: all clean test
|
||||
|
||||
all: fuzz.exe
|
||||
|
||||
CFLAGS=-g3 -fsanitize=address,fuzzer
|
||||
|
||||
fuzz.exe: main.o bad1.dll bad2.dll
|
||||
$(CC) $(CFLAGS) main.o -o fuzz.exe -L. -lbad1 -lbad2
|
||||
|
||||
bad1.dll: bad1.o
|
||||
$(CC) $(CFLAGS) -shared -o bad1.dll bad1.o
|
||||
|
||||
bad2.dll: bad2.o
|
||||
$(CC) $(CFLAGS) -shared -o bad2.dll bad2.o
|
||||
|
||||
|
||||
test: all
|
||||
LD_LIBRARY_PATH=. ./fuzz.exe
|
||||
|
||||
clean:
|
||||
rm -f *.dll *.exe *.exp *.pdb *.o *.lib
|
70
src/integration-tests/libfuzzer-linked-library/bad1.c
Normal file
70
src/integration-tests/libfuzzer-linked-library/bad1.c
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define LIBRARY_API __declspec(dllexport)
|
||||
#else
|
||||
#define LIBRARY_API
|
||||
#endif
|
||||
|
||||
int LIBRARY_API func1(const uint8_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 = 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;
|
||||
}
|
9
src/integration-tests/libfuzzer-linked-library/bad1.h
Normal file
9
src/integration-tests/libfuzzer-linked-library/bad1.h
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifndef BAD1_H
|
||||
#define BAD1_H
|
||||
|
||||
int func1(const uint8_t *data, size_t len);
|
||||
|
||||
#endif
|
70
src/integration-tests/libfuzzer-linked-library/bad2.c
Normal file
70
src/integration-tests/libfuzzer-linked-library/bad2.c
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define LIBRARY_API __declspec(dllexport)
|
||||
#else
|
||||
#define LIBRARY_API
|
||||
#endif
|
||||
|
||||
int LIBRARY_API func2(const uint8_t *data, size_t len) {
|
||||
int cnt = 0;
|
||||
|
||||
if (len < 4) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (data[0] == 'a') { cnt++; }
|
||||
if (data[1] == 'b') { cnt++; }
|
||||
if (data[2] == 'c') { 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;
|
||||
}
|
9
src/integration-tests/libfuzzer-linked-library/bad2.h
Normal file
9
src/integration-tests/libfuzzer-linked-library/bad2.h
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifndef BAD2_H
|
||||
#define BAD2_H
|
||||
|
||||
int func2(const uint8_t *data, size_t len);
|
||||
|
||||
#endif
|
14
src/integration-tests/libfuzzer-linked-library/main.c
Normal file
14
src/integration-tests/libfuzzer-linked-library/main.c
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bad1.h"
|
||||
#include "bad2.h"
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
func1(data, size);
|
||||
func2(data, size);
|
||||
return 0;
|
||||
}
|
@ -0,0 +1 @@
|
||||
good
|
Reference in New Issue
Block a user