Skip to content
Snippets Groups Projects
Commit 2a9dea01 authored by Toby Murray's avatar Toby Murray
Browse files

clag libFuzzer and coverage support from 2018. fix a bug found by libfuzzer

parent 5c824ec1
Branches
No related tags found
No related merge requests found
BINARY=passbook
#VULNS=vuln1 vuln2 vuln3 vuln4 vuln5
VBINARIES=$(BINARY) $(VULNS:%=${BINARY}-%)
TARGETS=$(VBINARIES) $(VBINARIES:%=%-san) $(VBINARIES:%=%-fuzz) $(VBINARIES:%=%-cov)
HEADERS=$(wildcard *.h)
# allow the user to provide additional CFLAGS by doing e.g. CFLAGS=blah make
CFLAGS += -W -Wall -Wpedantic -Wno-language-extension-token
# allow the user to override what clang we use by doing e.g. CLANG=blah make
CLANG ?= clang-6.0
CC=$(CLANG)
SAN_FLAGS ?= -fsanitize=address -fno-omit-frame-pointer
FUZZ_FLAGS ?= -DPASSBOOK_LIBFUZZER -fsanitize=fuzzer,address -fno-omit-frame-pointer
NO_STRICT_OVERFLOW_CFLAGS ?= -fwrapv -fno-strict-overflow -Wstrict-overflow
COV_FLAGS ?= -fprofile-instr-generate -fcoverage-mapping
default: $(TARGETS)
.PHONY: default
%: %.c $(HEADERS)
$(CC) $< $(CFLAGS) $(LDFLAGS) $(NO_STRICT_OVERFLOW_CFLAGS) -o $@
%-san: %.c $(HEADERS)
$(CLANG) $< $(CFLAGS) $(LDFLAGS) $(SAN_FLAGS) $(NO_STRICT_OVERFLOW_CFLAGS) -o $@
# build a self-fuzzing binary with libFuzzer
# needs a recent clang version (e.g. clang-6.0)
# then to run it:
# ./passbook-fuzz ~/tmp/corpus/ ~/tmp/findings/ -timeout=5 -only-ascii=1 -dict=libfuzzer-dict -max_total_time=1200 -print_final_stats=1
%-fuzz: %.c $(HEADERS)
$(CLANG) $< $(CFLAGS) $(LDFLAGS) $(FUZZ_FLAGS) $(NO_STRICT_OVERFLOW_CFLAGS) -o $@
%-cov: %.c $(HEADERS)
$(CLANG) $< $(CFLAGS) $(LDFLAGS) $(COV_FLAGS) $(NO_STRICT_OVERFLOW_CFLAGS) -o $@
clean:
rm -f $(TARGETS) *.profraw *.profdata
#!/bin/sh
if [ -z ${TOOL_SUFFIX+x} ]
then
# TOOL_SUFFIX not set
# try to intelligently set TOOL_SUFFIX
case $(uname) in
Linux)
TOOL_SUFFIX=-6.0
;;
Darwin)
TOOL_SUFFIX=
;;
*)
TOOL_SUFFIX=-6.0
esac
fi
CLANG=clang${TOOL_SUFFIX}
LLVM_PROFDATA=llvm-profdata${TOOL_SUFFIX}
LLVM_COV=llvm-cov${TOOL_SUFFIX}
if [ -z "$(which ${CLANG})" ]
then
echo "${CLANG} doesn't exist. Try setting TOOL_SUFFIX environment variable"
exit 1
fi
if [ -z "$(which ${LLVM_PROFDATA})" ]
then
echo "${LLVM_PROFDATA} doesn't exist. Try setting TOOL_SUFFIX environment variable"
exit 1
fi
if [ -z "$(which ${LLVM_COV})" ]
then
echo "${LLVM_COV} doesn't exist. Try setting TOOL_SUFFIX environment variable"
exit 1
fi
echo "using ${CLANG}, ${LLVM_PROFDATA} and ${LLVM_COV}"
export LLVM_PROFILE_FILE="passbook-%m.profraw"
if [ $# -lt 1 ]
then
echo "Usage: $0 inputfile1 [inputfile2 ...]"
exit 1
fi
rm -f passbook*.profraw passbook.profdata
echo "First re-building to make sure -DNDEBUG is turned on..."
rm -f passbook-cov
CLANG=${CLANG} CFLAGS="-DNDEBUG ${CFLAGS}" make passbook-cov
./passbook-cov $*
${LLVM_PROFDATA} merge -sparse passbook*.profraw -o passbook.profdata
${LLVM_COV} show ./passbook-cov -instr-profile=passbook.profdata
${LLVM_COV} report ./passbook-cov -instr-profile=passbook.profdata
...@@ -5,6 +5,13 @@ ...@@ -5,6 +5,13 @@
#include "debug.h" #include "debug.h"
#ifdef PASSBOOK_LIBFUZZER
#include <stdint.h>
const char LIBFUZZER_INPUT_FILE[] = "libFuzzerInput.tmp";
/* turn off tracing to make it run faster */
#define printf(...)
#define fprintf(...)
#endif
const char INSTRUCTION_PUT[] = "put"; const char INSTRUCTION_PUT[] = "put";
...@@ -88,12 +95,19 @@ static node_t * node_insert(node_t *p, node_t *q){ ...@@ -88,12 +95,19 @@ static node_t * node_insert(node_t *p, node_t *q){
if (p == NULL){ if (p == NULL){
return q; return q;
} }
if (q == NULL){
return p;
}
/* we store a pointer to a node pointer that remembers where in the /* we store a pointer to a node pointer that remembers where in the
tree the new node needs to be added */ tree the new node needs to be added */
node_t ** new = NULL; node_t ** new = NULL;
node_t * const start = p; node_t * const start = p;
while (new == NULL) { while (new == NULL) {
assert(q->url != NULL);
assert(p->url != NULL);
printf("Addr of dodgy node: %08x\n",(unsigned int)q);
strlen(q->url); // SEGV here
strlen(p->url);
int ret = strcmp(q->url,p->url); int ret = strcmp(q->url,p->url);
if (ret == 0){ if (ret == 0){
assert (q->left == NULL && q->right == NULL && "illegal insertion"); assert (q->left == NULL && q->right == NULL && "illegal insertion");
...@@ -123,6 +137,7 @@ static node_t * node_insert(node_t *p, node_t *q){ ...@@ -123,6 +137,7 @@ static node_t * node_insert(node_t *p, node_t *q){
/* returns a pointer to the tree with the node added or with the existing /* returns a pointer to the tree with the node added or with the existing
node updated if it was already present */ node updated if it was already present */
static node_t * put(node_t *p, const char *url, const cred_t cred){ static node_t * put(node_t *p, const char *url, const cred_t cred){
strlen(url);
return node_insert(p,node_new(url,cred)); return node_insert(p,node_new(url,cred));
} }
...@@ -529,7 +544,17 @@ static int run(FILE *f){ ...@@ -529,7 +544,17 @@ static int run(FILE *f){
return 0; return 0;
} }
#ifdef PASSBOOK_LIBFUZZER
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
FILE *f = fopen(LIBFUZZER_INPUT_FILE,"w");
fwrite(Data,Size,1,f);
fclose(f);
f = fopen(LIBFUZZER_INPUT_FILE,"r");
run(f);
fclose(f);
return 0; /* libFuzzer wants 0 returned always */
}
#else
int main(const int argc, const char * argv[]){ int main(const int argc, const char * argv[]){
cred_t cred1, cred2; cred_t cred1, cred2;
cred1.password = "asdfa"; cred1.password = "asdfa";
...@@ -553,6 +578,7 @@ int main(const int argc, const char * argv[]){ ...@@ -553,6 +578,7 @@ int main(const int argc, const char * argv[]){
} }
for (int i = 1; i<argc; i++){ for (int i = 1; i<argc; i++){
printf("Running on input file %s\n",argv[i]);
FILE *f; FILE *f;
if (strcmp(argv[i],"-") == 0){ if (strcmp(argv[i],"-") == 0){
f = stdin; f = stdin;
...@@ -566,7 +592,6 @@ int main(const int argc, const char * argv[]){ ...@@ -566,7 +592,6 @@ int main(const int argc, const char * argv[]){
int ans = run(f); int ans = run(f);
if (ans < 0){ if (ans < 0){
fprintf(stderr,"Error\n"); fprintf(stderr,"Error\n");
exit(1);
} }
/* do not close stdin */ /* do not close stdin */
if (f != stdin){ if (f != stdin){
...@@ -575,3 +600,4 @@ int main(const int argc, const char * argv[]){ ...@@ -575,3 +600,4 @@ int main(const int argc, const char * argv[]){
} }
return 0; return 0;
} }
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment