libfuzzer library integration tests (#681)

This commit is contained in:
bmc-msft
2021-03-17 16:18:10 -04:00
committed by GitHub
parent 4b07fdc455
commit f41f110af8
15 changed files with 401 additions and 0 deletions

View File

@ -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

View File

@ -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,

View 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-*

View 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;
}

View 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

View 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);
}

View File

@ -0,0 +1 @@
good

View 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

View File

@ -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

View 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;
}

View 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

View 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;
}

View 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

View 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;
}

View File

@ -0,0 +1 @@
good