apache-httpd: new fuzzers and more targets. (#6166)

This commit is contained in:
DavidKorczynski 2021-08-04 21:39:43 +01:00 committed by GitHub
parent ec3c914f22
commit 3c43288e55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 194 additions and 75 deletions

View File

@ -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 && \

View File

@ -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 \

View File

@ -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;
}

View File

@ -33,99 +33,148 @@ limitations under the License.
#include "ap_provider.h"
#include "ap_regex.h"
#include "ada_fuzz_header.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';
// Initialize fuzzing garbage collector. We use this to easily
// get data types seeded with random input from the fuzzer.
af_gb_init();
// 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");
const uint8_t *data2 = data;
size_t size2 = size;
// Pool initialisation
if (apr_pool_initialize() == APR_SUCCESS) {
apr_pool_t *pool = NULL;
apr_pool_create(&pool, NULL);
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 require a pool
ap_field_noparam(pool, new_str);
// 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);
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 *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);
}
char *d = malloc(size * 2);
ap_escape_errorlog_item(d, new_str, size * 2);
free(d);
// Pool initialisation
if (apr_pool_initialize() == APR_SUCCESS) {
apr_pool_t *pool = NULL;
apr_pool_create(&pool, NULL);
// base64
char *decoded = NULL;
decoded = ap_pbase64decode(pool, new_str);
ap_pbase64encode(pool, new_str);
// Targets that require a pool
ns3 = af_gb_get_null_terminated(&data2, &size2);
if (ns3 != NULL) {
ap_make_dirstr_parent(pool, ns3);
}
char *tmp_s = new_str;
ap_getword_conf2(pool, &tmp_s);
ap_field_noparam(pool, new_str);
// 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);
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);
// 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);
// This line causes some issues if something bad is allocated
ap_escape_quotes(pool, new_str);
apr_array_header_t *offers = NULL;
ap_parse_token_list_strict(pool, new_str, &offers, 0);
if (size > 2) {
ap_cstr_casecmpn(new_str, new_str + 2, size - 2);
}
char *tmp_null = NULL;
ap_pstr2_alnum(pool, new_str, &tmp_null);
char *d = malloc(size * 2);
ap_escape_errorlog_item(d, new_str, size * 2);
free(d);
// Word functions
tmp_s = new_str;
ap_getword(pool, &tmp_s, 0);
// base64
char *decoded = NULL;
decoded = ap_pbase64decode(pool, new_str);
ap_pbase64encode(pool, new_str);
tmp_s = new_str;
ap_getword_white_nc(pool, &tmp_s);
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);
}
tmp_s = new_str;
ap_get_token(pool, &tmp_s, 1);
char *tmp_s = new_str;
ap_getword_conf2(pool, &tmp_s);
tmp_s = new_str;
ap_escape_urlencoded(pool, tmp_s);
// str functions
ap_strcasecmp_match(tmp_s, new_dst);
ap_strcasestr(tmp_s, new_dst);
apr_interval_time_t timeout;
ap_timeout_parameter_parse(new_str, &timeout, "ms");
// 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);
tmp_s = new_str;
ap_content_type_tolower(tmp_s);
apr_array_header_t *offers = NULL;
ap_parse_token_list_strict(pool, new_str, &offers, 0);
// Cleanup
apr_pool_terminate();
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;
}