[hostap] Add hostap fuzzers (#2413)

This commit is contained in:
Marco Elver 2019-05-24 14:56:38 +02:00 committed by Max Moroz
parent 02a91a656b
commit d4c9198a03
4 changed files with 249 additions and 0 deletions

View File

@ -0,0 +1,23 @@
# Copyright 2019 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
FROM gcr.io/oss-fuzz-base/base-builder
MAINTAINER elver@google.com
RUN apt-get update && apt-get install -y make autoconf automake libtool g++
RUN git clone --depth 1 git://w1.fi/srv/git/hostap.git hostap
WORKDIR hostap
COPY build.sh $SRC/
COPY libfuzzer_entry.c $SRC/hostap/tests/

162
projects/hostap/build.sh Executable file
View File

@ -0,0 +1,162 @@
#!/bin/bash -eu
# Copyright 2019 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
cd 'tests'
# Make seed corpora
(
# Need clean environment for building test-tls used to create seed corpus.
unset CC
unset CXX
unset CFLAGS
unset CXXFLAGS
unset LDFLAGS
make clean
make test-tls
for x in client server; do
./test-tls $x write "${WORK}/test-tls-${x}.msg"
(cd "$WORK" && zip "${OUT}/test-tls-${x}-read_seed_corpus.zip" test-tls-${x}.msg)
done
(
cd p2p-fuzzer
zip "${OUT}/p2p-fuzzer-proberesp_seed_corpus.zip" proberesp*.dat
zip "${OUT}/p2p-fuzzer-action_seed_corpus.zip" go*.dat inv*.dat p2ps*.dat
)
(cd eapol-fuzzer && zip "${OUT}/eapol-fuzzer_seed_corpus.zip" *.dat)
(cd ap-mgmt-fuzzer && zip "${OUT}/ap-mgmt-fuzzer_seed_corpus.zip" multi.dat)
(cd wnm-fuzzer && zip "${OUT}/wnm-fuzzer_seed_corpus.zip" *.dat)
echo '{"a":[[]],"b":1,"c":"q","d":{"e":[{}]}}' > "${WORK}/test.json"
(cd "$WORK" && zip "${OUT}/test-json_seed_corpus.zip" *.json)
# TODO: test-x509
)
make clean
export LDO=$CXX
export LDFLAGS="$CXXFLAGS $LIB_FUZZING_ENGINE"
export CFLAGS="$CFLAGS -DTEST_LIBFUZZER -DCONFIG_NO_STDOUT_DEBUG"
# libFuzzer native targets (enabled via TEST_LIBFUZZER) ------------------
for target in json x509; do
make test-${target} TEST_FUZZ=y
cp -v "test-${target}" "${OUT}/"
done
# AFL compatible targets --------------------------------------------------
patch_afl_fuzzer() {
(
printf '#include <stddef.h>
char* get_fuzzer_input(const char*, size_t*);
void free_fuzzer_input(void*);
#define os_readfile get_fuzzer_input
#define os_free free_fuzzer_input
'
cat "$1"
) > "${1}_"
mv "${1}_" "$1"
}
print_ignore_leaks_options() {
cat <<EOF
[libfuzzer]
detect_leaks = 0
EOF
}
export CFLAGS="$CFLAGS -Dmain=fuzzer_main"
(
export OBJS="../libfuzzer_entry.o"
# ap-mgmt-fuzzer
patch_afl_fuzzer "ap-mgmt-fuzzer/ap-mgmt-fuzzer.c"
make clean
CFLAGS="$CFLAGS -DEXTRA_ARGS='\"-m\",'" \
make -C "ap-mgmt-fuzzer"
cp -v "ap-mgmt-fuzzer/ap-mgmt-fuzzer" "${OUT}/"
# wnm-fuzzer
patch_afl_fuzzer "wnm-fuzzer/wnm-fuzzer.c"
rm -v "libfuzzer_entry.o"
make -C "wnm-fuzzer"
cp -v "wnm-fuzzer/wnm-fuzzer" "${OUT}/"
# TODO: Investigate leak and remove if not false positive.
print_ignore_leaks_options > "${OUT}/wnm-fuzzer.options"
)
# The below Makefiles do not honor OBJS.
recompile_libfuzzer_entry() {
rm -vf "libfuzzer_entry.o"
$CC $CFLAGS -c -o "libfuzzer_entry.o" "libfuzzer_entry.c"
}
# test-tls variants
(
export LDFLAGS="$LDFLAGS libfuzzer_entry.o"
make clean
# test-tls uses fopen to open the input file.
sed -i '1i\
#define fopen fopen_fuzzer_input
' "test-tls.c"
CFLAGS="$CFLAGS -DEXTRA_ARGS=\"server\",\"read\"," \
recompile_libfuzzer_entry
make test-tls TEST_FUZZ=y
cp -v "test-tls" "${OUT}/test-tls-server-read"
CFLAGS="$CFLAGS -DEXTRA_ARGS=\"client\",\"read\"," \
recompile_libfuzzer_entry
make test-tls TEST_FUZZ=y
cp -v "test-tls" "${OUT}/test-tls-client-read"
)
(
export LIBS="../libfuzzer_entry.o"
# eapol-fuzzer
patch_afl_fuzzer "eapol-fuzzer/eapol-fuzzer.c"
make -C "eapol-fuzzer" clean
recompile_libfuzzer_entry
make -C "eapol-fuzzer"
cp -v "eapol-fuzzer/eapol-fuzzer" "${OUT}/"
# p2p-fuzzer variants
patch_afl_fuzzer "p2p-fuzzer/p2p-fuzzer.c"
make -C "p2p-fuzzer" clean
CFLAGS="$CFLAGS -DEXTRA_ARGS=\"action\"," \
recompile_libfuzzer_entry
make -C "p2p-fuzzer"
cp -v "p2p-fuzzer/p2p-fuzzer" "${OUT}/p2p-fuzzer-action"
CFLAGS="$CFLAGS -DEXTRA_ARGS=\"proberesp\"," \
recompile_libfuzzer_entry
make -C "p2p-fuzzer"
cp -v "p2p-fuzzer/p2p-fuzzer" "${OUT}/p2p-fuzzer-proberesp"
)
# Copy required data.
cp -a "hwsim" "${OUT}/"

View File

@ -0,0 +1,56 @@
#define _GNU_SOURCE
#include <assert.h>
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef EXTRA_ARGS
#define EXTRA_ARGS
#endif
#define DUMMY_FILE_NAME "/invalid/path/do/not/use"
static size_t input_size = 0;
static char* input_data = NULL;
static int use_count = 0;
int fuzzer_main(int argc, char *argv[]);
char* get_fuzzer_input(const char* fname, size_t *size) {
assert(!strcmp(fname, DUMMY_FILE_NAME));
*size = input_size;
++use_count;
return input_data;
}
void free_fuzzer_input(char* ptr) {
assert(ptr == input_data);
}
FILE* fopen_fuzzer_input(const char* fname, const char* mode) {
assert(!strcmp(fname, DUMMY_FILE_NAME));
++use_count;
return fmemopen(input_data, input_size, mode);
}
// Entry point for libFuzzer fuzzer, that wraps main of a fuzzer compatible with
// AFL (where input is passed via a file).
//
// TODO: Ideally, should add native libFuzzer entry to project's fuzzer, as this
// approach has noticable performance implications.
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
char* argv[] = {"fuzzer", EXTRA_ARGS DUMMY_FILE_NAME};
input_size = size;
input_data = (char*) data;
fuzzer_main(sizeof(argv) / sizeof(char*), argv);
if (use_count == 0) {
printf("ERROR: input not used!\n");
}
return 0;
}

View File

@ -0,0 +1,8 @@
homepage: "https://w1.fi/cvs.html"
primary_contact: "j@w1.fi"
auto_ccs:
- "elver@google.com"
sanitizers:
- address
- undefined
- memory