Skip to content

Commit e27f50b

Browse files
committed
fnmatch: add fuzzer for fnmatch testing
1 parent 29e3549 commit e27f50b

File tree

8 files changed

+126
-2
lines changed

8 files changed

+126
-2
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ missing
3030
/curl_fuzzer_dict_seed_corpus.zip
3131
/curl_fuzzer_file
3232
/curl_fuzzer_file_seed_corpus.zip
33+
/curl_fuzzer_fnmatch
34+
/curl_fuzzer_fnmatch_seed_corpus.zip
3335
/curl_fuzzer_ftp
3436
/curl_fuzzer_ftp_seed_corpus.zip
3537
/curl_fuzzer_gopher

Makefile.am

+7-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ ACLOCAL_AMFLAGS = -I m4
2525
@CODE_COVERAGE_RULES@
2626

2727
# Include debug symbols by default as recommended by libfuzzer.
28-
AM_CXXFLAGS = -g -I@INSTALLDIR@/include
28+
AM_CXXFLAGS = -g -I@INSTALLDIR@/include -I@INSTALLDIR@/utfuzzer
2929

3030
LIBS = -lpthread -lm
3131

@@ -38,6 +38,7 @@ LIB_FUZZING_ENGINE ?= libstandaloneengine.a
3838
FUZZPROGS = curl_fuzzer \
3939
curl_fuzzer_dict \
4040
curl_fuzzer_file \
41+
curl_fuzzer_fnmatch \
4142
curl_fuzzer_ftp \
4243
curl_fuzzer_gopher \
4344
curl_fuzzer_http \
@@ -112,6 +113,11 @@ curl_fuzzer_tftp_SOURCES = $(COMMON_SOURCES)
112113
curl_fuzzer_tftp_CXXFLAGS = $(COMMON_FLAGS) -DFUZZ_PROTOCOLS_TFTP
113114
curl_fuzzer_tftp_LDADD = $(COMMON_LDADD)
114115

116+
# Unit test fuzzers
117+
curl_fuzzer_fnmatch_SOURCES = fuzz_fnmatch.cc
118+
curl_fuzzer_fnmatch_CXXFLAGS = $(COMMON_FLAGS)
119+
curl_fuzzer_fnmatch_LDADD = $(COMMON_LDADD)
120+
115121
# Create the seed corpora zip files.
116122
zip:
117123
./create_zip.sh
8 Bytes
Binary file not shown.
15 Bytes
Binary file not shown.

fuzz_fnmatch.cc

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/***************************************************************************
2+
* _ _ ____ _
3+
* Project ___| | | | _ \| |
4+
* / __| | | | |_) | |
5+
* | (__| |_| | _ <| |___
6+
* \___|\___/|_| \_\_____|
7+
*
8+
* Copyright (C) 2017, Max Dymond, <[email protected]>, et al.
9+
*
10+
* This software is licensed as described in the file COPYING, which
11+
* you should have received as part of this distribution. The terms
12+
* are also available at https://curl.haxx.se/docs/copyright.html.
13+
*
14+
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
15+
* copies of the Software, and permit persons to whom the Software is
16+
* furnished to do so, under the terms of the COPYING file.
17+
*
18+
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19+
* KIND, either express or implied.
20+
*
21+
***************************************************************************/
22+
23+
extern "C"
24+
{
25+
#include <stdlib.h>
26+
#include <signal.h>
27+
#include <string.h>
28+
#include <unistd.h>
29+
#include <inttypes.h>
30+
#include <curl/curl.h>
31+
#include "curl_fnmatch.h"
32+
}
33+
34+
/* #define DEBUG(STMT) STMT */
35+
#define DEBUG(STMT)
36+
37+
/**
38+
* Fuzzing entry point. This function is passed a buffer containing a test
39+
* case. This test case should drive the CURL fnmatch function.
40+
*/
41+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
42+
{
43+
const char *string_data = (const char *)data;
44+
const char *pattern;
45+
const char *contents;
46+
int pattern_len;
47+
int fnrc;
48+
49+
DEBUG(printf("\nSize is %lu bytes \n", size));
50+
51+
/* The string requires at least two null terminators. Anything
52+
smaller is an error. */
53+
if(size < 2) {
54+
DEBUG(printf("Size is too small. \n"));
55+
goto EXIT_LABEL;
56+
}
57+
58+
/* The data should be split into two strings - the pattern and the
59+
string to match on. The data should be null-terminated. */
60+
if(data[size - 1] != 0) {
61+
DEBUG(printf("Not null terminated \n"));
62+
goto EXIT_LABEL;
63+
}
64+
65+
pattern_len = strnlen(string_data, size);
66+
67+
DEBUG(printf("Pattern length %d \n", pattern_len));
68+
69+
/* Check to see if the string length is valid. Because pattern_len
70+
doesn't include a null terminator, we should check to see if the length
71+
equals the full buffer size with or without a null terminator. */
72+
if((pattern_len >= size - 1) ||
73+
(string_data[pattern_len] != 0)) {
74+
/* The string was not valid. */
75+
DEBUG(printf("Pattern string was invalid \n"));
76+
goto EXIT_LABEL;
77+
}
78+
79+
/* Set up the pointers for the pattern and string. */
80+
pattern = string_data;
81+
contents = &string_data[pattern_len + 1];
82+
83+
/* Sanity check the size of the strings. We should have two strings
84+
less two null terminators. */
85+
if(strlen(contents) + pattern_len != size - 2) {
86+
DEBUG(printf("Unexpected lengths: %lu + %d != %lu - 2 \n",
87+
strlen(contents),
88+
pattern_len,
89+
size));
90+
goto EXIT_LABEL;
91+
}
92+
93+
DEBUG(printf("Pattern: '%s' \n", pattern));
94+
DEBUG(printf("Contents: '%s' \n", contents));
95+
96+
/* Call the fuzz function. */
97+
fnrc = Curl_fnmatch(NULL, pattern, contents);
98+
99+
(void)fnrc;
100+
DEBUG(printf("Curl_fnmatch returned %d \n", fnrc));
101+
102+
EXIT_LABEL:
103+
104+
return 0;
105+
}

fuzz_targets

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#!/bin/bash
22

3-
export FUZZ_TARGETS="curl_fuzzer_dict curl_fuzzer_file curl_fuzzer_ftp curl_fuzzer_gopher curl_fuzzer_http curl_fuzzer_imap curl_fuzzer_ldap curl_fuzzer_pop3 curl_fuzzer_rtmp curl_fuzzer_rtsp curl_fuzzer_scp curl_fuzzer_sftp curl_fuzzer_smb curl_fuzzer_smtp curl_fuzzer_tftp curl_fuzzer"
3+
export FUZZ_TARGETS="curl_fuzzer_dict curl_fuzzer_file curl_fuzzer_fnmatch curl_fuzzer_ftp curl_fuzzer_gopher curl_fuzzer_http curl_fuzzer_imap curl_fuzzer_ldap curl_fuzzer_pop3 curl_fuzzer_rtmp curl_fuzzer_rtsp curl_fuzzer_scp curl_fuzzer_sftp curl_fuzzer_smb curl_fuzzer_smtp curl_fuzzer_tftp curl_fuzzer"

generate_fnmatch.sh

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
3+
# Redirect the output of this script to a test file.
4+
printf "$1\0$2\0"

install_curl.sh

+7
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,11 @@ pushd ${SRCDIR}
5050
make
5151
make install
5252

53+
# Make any explicit folders which are post install
54+
UTFUZZDIR=${INSTALLDIR}/utfuzzer
55+
mkdir -p ${UTFUZZDIR}
56+
57+
# Copy header files.
58+
cp -v lib/curl_fnmatch.h ${UTFUZZDIR}
59+
5360
popd

0 commit comments

Comments
 (0)