diff --git a/projects/haproxy/Dockerfile b/projects/haproxy/Dockerfile new file mode 100755 index 000000000..c43f14153 --- /dev/null +++ b/projects/haproxy/Dockerfile @@ -0,0 +1,24 @@ +# Copyright 2020 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 david@adalogics.com +RUN apt-get update && apt-get install -y make +RUN git clone https://github.com/haproxy/haproxy + +WORKDIR $SRC + +COPY build.sh $SRC +COPY fuzz* $SRC/ diff --git a/projects/haproxy/build.sh b/projects/haproxy/build.sh new file mode 100755 index 000000000..7dc4d4e97 --- /dev/null +++ b/projects/haproxy/build.sh @@ -0,0 +1,43 @@ +#!/bin/bash -eu +# Copyright 2020 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. +# +################################################################################ +export ORIG_CFLAGS=${CFLAGS} +cd haproxy + +# Fix some things in the Makefile where there are no options available +sed 's/LD = $(CC)/LD = ${CXX}/g' -i Makefile +sed 's/CC = gcc/#CC = gcc/g' -i Makefile +sed 's/CFLAGS = $(ARCH_FLAGS) $(CPU_CFLAGS) $(DEBUG_CFLAGS) $(SPEC_CFLAGS)/CFLAGS = $(ARCH_FLAGS) $(CPU_CFLAGS) $(DEBUG_CFLAGS) $(SPEC_CFLAGS) ${ORIG_CFLAGS}/g' -i Makefile +sed 's/LDFLAGS = $(ARCH_FLAGS) -g/LDFLAGS = $(ARCH_FLAGS) -g ${CXXFLAGS}/g' -i Makefile +make TARGET=generic + +cd contrib/hpack +cp /src/fuzz_hpack_decode.c . +$CC $CFLAGS -g -I../../include -I../../ebtree -fwrapv -fno-strict-aliasing -c fuzz_hpack_decode.c -o fuzz_hpack_decode.o +$CXX $CXXFLAGS $LIB_FUZZING_ENGINE ./fuzz_hpack_decode.o -o $OUT/fuzz_hpack_decode + +# Make a copy of the main file since it has many global functions we need to declare +# We dont want the main function but we need the rest of the stuff in haproxy.c +cd /src/haproxy +sed 's/int main(int argc/int main2(int argc/g' -i ./src/haproxy.c +$CC $CFLAGS -Iinclude -Iebtree -g -DUSE_POLL -DUSE_TPROXY -DCONFIG_HAPROXY_VERSION=\"\" -DCONFIG_HAPROXY_DATE=\"\" -c -o ./src/haproxy.o ./src/haproxy.c +ar cr libetree.a ./ebtree/*.o +ar cr libhaproxy.a ./src/*.o + +# Now compile more fuzzers +cp $SRC/fuzz_cfg_parser.c . +$CC $CFLAGS -Iinclude -Iebtree -g -DUSE_POLL -DUSE_TPROXY -DCONFIG_HAPROXY_VERSION=\"\" -DCONFIG_HAPROXY_DATE=\"\" -c -o fuzz_cfg_parser.o fuzz_cfg_parser.c +$CXX -g $CXXFLAGS $LIB_FUZZING_ENGINE fuzz_cfg_parser.o libhaproxy.a libetree.a -o $OUT/fuzz_cfg_parser diff --git a/projects/haproxy/fuzz_cfg_parser.c b/projects/haproxy/fuzz_cfg_parser.c new file mode 100644 index 000000000..366673408 --- /dev/null +++ b/projects/haproxy/fuzz_cfg_parser.c @@ -0,0 +1,40 @@ +/* +# Copyright 2020 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. +# +################################################################################ +*/ +#include +#include +#include + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + char filename[256]; + sprintf(filename, "/tmp/libfuzzer.%d", getpid()); + + FILE *fp = fopen(filename, "wb"); + if (!fp) + return 0; + fwrite(data, size, 1, fp); + fclose(fp); + + // Fuzz the cfg parser + readcfgfile(filename); + + unlink(filename); + + return 0; +} diff --git a/projects/haproxy/fuzz_hpack_decode.c b/projects/haproxy/fuzz_hpack_decode.c new file mode 100644 index 000000000..563f91b0d --- /dev/null +++ b/projects/haproxy/fuzz_hpack_decode.c @@ -0,0 +1,74 @@ +/* + * # Copyright 2020 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. + * # + * ################################################################################ + * */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_RQ_SIZE 65536 +#define MAX_HDR_NUM 1000 + +char hex[MAX_RQ_SIZE*3+3]; // enough for "[ XX]* \0" +uint8_t buf[MAX_RQ_SIZE]; + +char trash_buf[MAX_RQ_SIZE]; +char tmp_buf[MAX_RQ_SIZE]; + +struct buffer trash = { .area = trash_buf, .data = 0, .size = sizeof(trash_buf) }; +struct buffer tmp = { .area = tmp_buf, .data = 0, .size = sizeof(tmp_buf) }; + + +/* Empty function we dont need - we just need a callback */ +void debug_hexdump(FILE *out, const char *pfx, const char *buf, + unsigned int baseaddr, int len) +{ } + +// These must be included here +#include "../src/hpack-huff.c" +#include "../src/hpack-tbl.c" +#include "../src/hpack-dec.c" + + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size){ + char *new_str = (char *)malloc(size+1); + struct hpack_dht *dht; + int dht_size = 4096; + if (new_str == NULL){ + return 0; + } + memcpy(new_str, data, size); + new_str[size] = '\0'; + struct http_hdr list[MAX_HDR_NUM]; + + dht = hpack_dht_alloc(dht_size); + hpack_decode_frame(dht, new_str, size, list,sizeof(list)/sizeof(list[0]), &tmp); + if (dht != NULL) + { + free(dht); + } + + free(new_str); + return 0; +} diff --git a/projects/haproxy/project.yaml b/projects/haproxy/project.yaml new file mode 100755 index 000000000..2b66c5988 --- /dev/null +++ b/projects/haproxy/project.yaml @@ -0,0 +1,9 @@ +homepage: "https://github.com/haproxy/haproxy" +primary_contact: "fuzzing@haproxy.org" +language: c++ +auto_ccs: + - "david@adalogics.com" + - "adam@adalogics.com" +sanitizers: + - address + - memory