aboutsummaryrefslogtreecommitdiff
path: root/projects/apache-httpd
diff options
context:
space:
mode:
authorDavidKorczynski <david@adalogics.com>2021-08-04 21:39:43 +0100
committerGitHub <noreply@github.com>2021-08-04 21:39:43 +0100
commit3c43288e553fd8f43b2e050f382098cbc97f3ceb (patch)
treee8ed408f50256253e3eb7ca32382850dff7bb443 /projects/apache-httpd
parentec3c914f22c9b6d4207f9e74abcfc7f3cd81cd40 (diff)
downloadoss-fuzz-3c43288e553fd8f43b2e050f382098cbc97f3ceb.tar.gz
apache-httpd: new fuzzers and more targets. (#6166)
Diffstat (limited to 'projects/apache-httpd')
-rw-r--r--projects/apache-httpd/Dockerfile3
-rwxr-xr-xprojects/apache-httpd/build.sh6
-rw-r--r--projects/apache-httpd/fuzz_uri.c65
-rw-r--r--projects/apache-httpd/fuzz_utils.c229
4 files changed, 211 insertions, 92 deletions
diff --git a/projects/apache-httpd/Dockerfile b/projects/apache-httpd/Dockerfile
index bb6a63ee9..e1d46896d 100644
--- a/projects/apache-httpd/Dockerfile
+++ b/projects/apache-httpd/Dockerfile
@@ -17,6 +17,9 @@
FROM gcr.io/oss-fuzz-base/base-builder
RUN apt-get update && apt-get install -y make autoconf automake libtool wget libpcre3 \
libpcre3-dev uuid-dev pkg-config libtool-bin
+
+RUN git clone https://github.com/AdaLogics/fuzz-headers
+
RUN wget https://github.com/libexpat/libexpat/releases/download/R_2_4_1/expat-2.4.1.tar.gz && \
tar -xf expat-2.4.1.tar.gz && \
cd expat-2.4.1 && \
diff --git a/projects/apache-httpd/build.sh b/projects/apache-httpd/build.sh
index a1383577b..eed379dbd 100755
--- a/projects/apache-httpd/build.sh
+++ b/projects/apache-httpd/build.sh
@@ -27,8 +27,10 @@ svn checkout https://svn.apache.org/repos/asf/apr/apr/trunk/ srclib/apr
make
# Build the fuzzers
-for fuzzname in utils parse tokenize addr_parse; do
- $CC $CFLAGS $LIB_FUZZING_ENGINE -I./include -I./os/unix -I./srclib/apr/include -I./srclib/apr-util/include/ \
+for fuzzname in utils parse tokenize addr_parse uri; do
+ $CC $CFLAGS $LIB_FUZZING_ENGINE \
+ -I$SRC/fuzz-headers/lang/c -I./include -I./os/unix \
+ -I./srclib/apr/include -I./srclib/apr-util/include/ \
$SRC/fuzz_${fuzzname}.c -o $OUT/fuzz_${fuzzname} \
./modules.o buildmark.o \
-Wl,--start-group ./server/.libs/libmain.a \
diff --git a/projects/apache-httpd/fuzz_uri.c b/projects/apache-httpd/fuzz_uri.c
new file mode 100644
index 000000000..789b96f05
--- /dev/null
+++ b/projects/apache-httpd/fuzz_uri.c
@@ -0,0 +1,65 @@
+/* Copyright 2021 Google LLC
+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 "apr.h"
+#include "apr_file_io.h"
+#include "apr_poll.h"
+#include "apr_portable.h"
+#include "apr_proc_mutex.h"
+#include "apr_signal.h"
+#include "apr_strings.h"
+#include "apr_thread_mutex.h"
+#include "apr_thread_proc.h"
+
+#define APR_WANT_STRFUNC
+#include "apr_file_io.h"
+#include "apr_fnmatch.h"
+#include "apr_want.h"
+
+#include "apr_poll.h"
+#include "apr_want.h"
+
+#include "apr_uri.h"
+
+#include "ap_config.h"
+#include "ap_expr.h"
+#include "ap_listen.h"
+#include "ap_provider.h"
+#include "ap_regex.h"
+
+#include "ada_fuzz_header.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ af_gb_init();
+ const uint8_t *data2 = data;
+ size_t size2 = size;
+
+ // Get a NULL terminated string
+ char *cstr = af_gb_get_null_terminated(&data2, &size2);
+
+ // Fuzz URI routines
+ if (cstr && apr_pool_initialize() == APR_SUCCESS) {
+ apr_pool_t *pool = NULL;
+ apr_pool_create(&pool, NULL);
+
+ apr_uri_t tmp_uri;
+ if (apr_uri_parse(pool, cstr, &tmp_uri) == APR_SUCCESS) {
+ apr_uri_unparse(pool, &tmp_uri, 0);
+ }
+ apr_uri_parse_hostinfo(pool, cstr, &tmp_uri);
+
+ // Cleanup
+ apr_pool_terminate();
+ }
+
+ af_gb_cleanup();
+ return 0;
+}
diff --git a/projects/apache-httpd/fuzz_utils.c b/projects/apache-httpd/fuzz_utils.c
index 1ced86fe5..577c1cf90 100644
--- a/projects/apache-httpd/fuzz_utils.c
+++ b/projects/apache-httpd/fuzz_utils.c
@@ -33,99 +33,148 @@ limitations under the License.
#include "ap_provider.h"
#include "ap_regex.h"
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
- char *new_str = (char *)malloc(size + 1);
- if (new_str == NULL) {
- return 0;
- }
- memcpy(new_str, data, size);
- new_str[size] = '\0';
-
- // Targets that do not require a pool
- ap_cstr_casecmp(new_str, new_str);
- ap_getparents(new_str);
- ap_unescape_url(new_str);
- ap_unescape_urlencoded(new_str);
- ap_strcmp_match(new_str, "AAAAAABDKJSAD");
-
- // Pool initialisation
- if (apr_pool_initialize() == APR_SUCCESS) {
- apr_pool_t *pool = NULL;
- apr_pool_create(&pool, NULL);
-
- // Targets that require a pool
- ap_field_noparam(pool, new_str);
-
- ap_escape_shell_cmd(pool, new_str);
- ap_os_escape_path(pool, new_str, 0);
- ap_escape_html2(pool, new_str, 0);
- ap_escape_logitem(pool, new_str);
-
- // This line causes some issues if something bad is allocated
- ap_escape_quotes(pool, new_str);
-
- if (size > 2) {
- ap_cstr_casecmpn(new_str, new_str + 2, size - 2);
- }
-
- char *d = malloc(size * 2);
- ap_escape_errorlog_item(d, new_str, size * 2);
- free(d);
-
- // base64
- char *decoded = NULL;
- decoded = ap_pbase64decode(pool, new_str);
- ap_pbase64encode(pool, new_str);
-
- char *tmp_s = new_str;
- ap_getword_conf2(pool, &tmp_s);
-
- // str functions
- ap_strcasecmp_match(tmp_s, "asdfkj");
- ap_strcasestr(tmp_s, "AAAAAAAAAAAAAA");
- ap_strcasestr(tmp_s, "AasdfasbA");
- ap_strcasestr(tmp_s, "1341234");
- ap_strcasestr("AAAAAAAAAAAAAA", tmp_s);
- ap_strcasestr("AasdfasbA", tmp_s);
- ap_strcasestr("1341234", tmp_s);
-
- // List functions
- tmp_s = new_str;
- ap_get_list_item(pool, &tmp_s);
- tmp_s = new_str;
- ap_find_list_item(pool, &tmp_s, "kjahsdfkj");
- ap_find_token(pool, tmp_s, "klsjdfk");
- ap_find_last_token(pool, tmp_s, "sdadf");
- ap_is_chunked(pool, tmp_s);
-
- apr_array_header_t *offers = NULL;
- ap_parse_token_list_strict(pool, new_str, &offers, 0);
-
- char *tmp_null = NULL;
- ap_pstr2_alnum(pool, new_str, &tmp_null);
+#include "ada_fuzz_header.h"
- // Word functions
- tmp_s = new_str;
- ap_getword(pool, &tmp_s, 0);
- tmp_s = new_str;
- ap_getword_white_nc(pool, &tmp_s);
-
- tmp_s = new_str;
- ap_get_token(pool, &tmp_s, 1);
-
- tmp_s = new_str;
- ap_escape_urlencoded(pool, tmp_s);
-
- apr_interval_time_t timeout;
- ap_timeout_parameter_parse(new_str, &timeout, "ms");
-
- tmp_s = new_str;
- ap_content_type_tolower(tmp_s);
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ // Initialize fuzzing garbage collector. We use this to easily
+ // get data types seeded with random input from the fuzzer.
+ af_gb_init();
+
+ const uint8_t *data2 = data;
+ size_t size2 = size;
+
+ char *new_str = af_gb_get_null_terminated(&data2, &size2);
+ char *new_dst = af_gb_get_null_terminated(&data2, &size2);
+ if (new_str != NULL && new_dst != NULL) {
+
+ // Targets that do not require a pool
+ ap_cstr_casecmp(new_str, new_str);
+ ap_getparents(new_str);
+ ap_unescape_url(new_str);
+ ap_unescape_urlencoded(new_str);
+ ap_strcmp_match(new_str, new_dst);
+
+ char *ns3 = af_gb_get_null_terminated(&data2, &size2);
+ if (ns3 != NULL) {
+ ap_no2slash(ns3);
+ }
+ char *ns10 = af_gb_get_null_terminated(&data2, &size2);
+ char *ns11 = af_gb_get_null_terminated(&data2, &size2);
+ if (ns10 != NULL && ns11 != NULL) {
+ ap_escape_path_segment_buffer(ns10, ns11);
+ }
- // Cleanup
- apr_pool_terminate();
+ // Pool initialisation
+ if (apr_pool_initialize() == APR_SUCCESS) {
+ apr_pool_t *pool = NULL;
+ apr_pool_create(&pool, NULL);
+
+ // Targets that require a pool
+ ns3 = af_gb_get_null_terminated(&data2, &size2);
+ if (ns3 != NULL) {
+ ap_make_dirstr_parent(pool, ns3);
+ }
+
+ ap_field_noparam(pool, new_str);
+
+ ap_escape_shell_cmd(pool, new_str);
+ ap_os_escape_path(pool, new_str, 0);
+ ap_escape_html2(pool, new_str, 0);
+ ap_escape_logitem(pool, new_str);
+
+ // This line causes some issues if something bad is allocated
+ ap_escape_quotes(pool, new_str);
+
+ if (size > 2) {
+ ap_cstr_casecmpn(new_str, new_str + 2, size - 2);
+ }
+
+ char *d = malloc(size * 2);
+ ap_escape_errorlog_item(d, new_str, size * 2);
+ free(d);
+
+ // base64
+ char *decoded = NULL;
+ decoded = ap_pbase64decode(pool, new_str);
+ ap_pbase64encode(pool, new_str);
+
+ char *ns12 = af_gb_get_null_terminated(&data2, &size2);
+ if (ns12 != NULL) {
+ char *d;
+ apr_size_t dlen;
+ ap_pbase64decode_strict(pool, ns12, &d, &dlen);
+ }
+
+ char *tmp_s = new_str;
+ ap_getword_conf2(pool, &tmp_s);
+
+ // str functions
+ ap_strcasecmp_match(tmp_s, new_dst);
+ ap_strcasestr(tmp_s, new_dst);
+
+ // List functions
+ tmp_s = new_str;
+ ap_get_list_item(pool, &tmp_s);
+ tmp_s = new_str;
+ ap_find_list_item(pool, &tmp_s, "kjahsdfkj");
+ ap_find_token(pool, tmp_s, "klsjdfk");
+ ap_find_last_token(pool, tmp_s, "sdadf");
+ ap_is_chunked(pool, tmp_s);
+
+ apr_array_header_t *offers = NULL;
+ ap_parse_token_list_strict(pool, new_str, &offers, 0);
+
+ char *tmp_null = NULL;
+ ap_pstr2_alnum(pool, new_str, &tmp_null);
+
+ // Word functions
+ tmp_s = new_str;
+ ap_getword(pool, &tmp_s, 0);
+
+ tmp_s = new_str;
+ ap_getword_white_nc(pool, &tmp_s);
+
+ tmp_s = new_str;
+ ap_get_token(pool, &tmp_s, 1);
+
+ tmp_s = new_str;
+ ap_escape_urlencoded(pool, tmp_s);
+
+ apr_interval_time_t timeout;
+ ap_timeout_parameter_parse(new_str, &timeout, "ms");
+
+ tmp_s = new_str;
+ ap_content_type_tolower(tmp_s);
+
+
+ char filename[256];
+ sprintf(filename, "/tmp/libfuzzer.%d", getpid());
+ FILE *fp = fopen(filename, "wb");
+ fwrite(data, size, 1, fp);
+ fclose(fp);
+
+ // Fuzzer logic here
+ ap_configfile_t *cfg;
+ ap_pcfg_openfile(&cfg, pool, filename);
+ char tmp_line[100];
+ if ((af_get_short(&data2, &size2) % 2) == 0) {
+ ap_cfg_getline(tmp_line, 100, cfg);
+ }
+ else {
+ cfg->getstr = NULL;
+ ap_cfg_getline(tmp_line, 100, cfg);
+ }
+ // Fuzzer logic end
+
+ unlink(filename);
+
+ // Cleanup
+ apr_pool_terminate();
+ }
}
- free(new_str);
+
+ // Cleanup all of the memory allocated by the fuzz headers.
+ af_gb_cleanup();
return 0;
}