Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Commit

Permalink
libfuzzer library integration tests (#681)
Browse files Browse the repository at this point in the history
  • Loading branch information
bmc-msft authored Mar 17, 2021
1 parent 4b07fdc commit f41f110
Show file tree
Hide file tree
Showing 15 changed files with 401 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
38 changes: 38 additions & 0 deletions src/integration-tests/integration-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,32 @@ class Integration(BaseModel):
},
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,
Expand Down Expand Up @@ -140,6 +166,18 @@ class Integration(BaseModel):
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,
Expand Down
18 changes: 18 additions & 0 deletions src/integration-tests/libfuzzer-dlopen/Makefile
Original file line number Diff line number Diff line change
@@ -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 changes: 64 additions & 0 deletions src/integration-tests/libfuzzer-dlopen/bad.c
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions src/integration-tests/libfuzzer-dlopen/bad.h
Original file line number Diff line number Diff line change
@@ -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 changes: 39 additions & 0 deletions src/integration-tests/libfuzzer-dlopen/main.c
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions src/integration-tests/libfuzzer-dlopen/seeds/good.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
good
22 changes: 22 additions & 0 deletions src/integration-tests/libfuzzer-linked-library/Makefile
Original file line number Diff line number Diff line change
@@ -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
23 changes: 23 additions & 0 deletions src/integration-tests/libfuzzer-linked-library/Makefile.windows
Original file line number Diff line number Diff line change
@@ -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 changes: 70 additions & 0 deletions src/integration-tests/libfuzzer-linked-library/bad1.c
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions src/integration-tests/libfuzzer-linked-library/bad1.h
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit f41f110

Please sign in to comment.