aboutsummaryrefslogtreecommitdiff
path: root/tests/fuzz/curl_fuzzer.cc
diff options
context:
space:
mode:
authorMax Dymond <cmeister2@gmail.com>2017-09-02 22:40:01 +0100
committerDaniel Stenberg <daniel@haxx.se>2017-09-08 15:00:55 +0200
commit261da2a6685c0185283dbf72ce543e9fd81e9bd8 (patch)
treed112cbe762ba1eff209b0a8eadd0fef16601e368 /tests/fuzz/curl_fuzzer.cc
parent1ae2704d6edf02c218b7e30fc2e13ce52a991bea (diff)
ossfuzz: add some more handled CURL options
Add support for HEADER, COOKIE, RANGE, CUSTOMREQUEST, MAIL_RECIPIENT, MAIL_FROM and uploading data.
Diffstat (limited to 'tests/fuzz/curl_fuzzer.cc')
-rw-r--r--tests/fuzz/curl_fuzzer.cc106
1 files changed, 86 insertions, 20 deletions
diff --git a/tests/fuzz/curl_fuzzer.cc b/tests/fuzz/curl_fuzzer.cc
index 92bedf92e..bbf91c222 100644
--- a/tests/fuzz/curl_fuzzer.cc
+++ b/tests/fuzz/curl_fuzzer.cc
@@ -63,6 +63,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
}
/* Do the CURL stuff! */
+ if(fuzz.header_list != NULL) {
+ curl_easy_setopt(fuzz.easy, CURLOPT_HTTPHEADER, fuzz.header_list);
+ }
+
+ if(fuzz.mail_recipients_list != NULL) {
+ curl_easy_setopt(fuzz.easy, CURLOPT_MAIL_RCPT, fuzz.mail_recipients_list);
+ }
+
curl_easy_perform(fuzz.easy);
EXIT_LABEL:
@@ -122,8 +130,14 @@ int fuzz_initialize_fuzz_data(FUZZ_DATA *fuzz,
CURLOPT_SOCKOPTFUNCTION,
fuzz_sockopt_callback));
- /* Can enable verbose mode */
- /* FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_VERBOSE, 1L)); */
+ /* Set the standard read function callback. */
+ FTRY(curl_easy_setopt(fuzz->easy,
+ CURLOPT_READFUNCTION,
+ fuzz_read_callback));
+ FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_READDATA, fuzz));
+
+ /* Can enable verbose mode by changing 0L to 1L */
+ FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_VERBOSE, 0L));
/* Set up the state parser */
fuzz->state.data = data;
@@ -143,6 +157,20 @@ void fuzz_terminate_fuzz_data(FUZZ_DATA *fuzz)
fuzz_free((void **)&fuzz->username);
fuzz_free((void **)&fuzz->password);
fuzz_free((void **)&fuzz->postfields);
+ fuzz_free((void **)&fuzz->cookie);
+ fuzz_free((void **)&fuzz->range);
+ fuzz_free((void **)&fuzz->customrequest);
+ fuzz_free((void **)&fuzz->mail_from);
+
+ if(fuzz->header_list != NULL) {
+ curl_slist_free_all(fuzz->header_list);
+ fuzz->header_list = NULL;
+ }
+
+ if(fuzz->mail_recipients_list != NULL) {
+ curl_slist_free_all(fuzz->mail_recipients_list);
+ fuzz->mail_recipients_list = NULL;
+ }
if(fuzz->easy != NULL) {
curl_easy_cleanup(fuzz->easy);
@@ -217,6 +245,31 @@ static int fuzz_sockopt_callback(void *ptr,
}
/**
+ * Callback function for doing data uploads.
+ */
+static size_t fuzz_read_callback(char *buffer,
+ size_t size,
+ size_t nitems,
+ void *ptr)
+{
+ FUZZ_DATA *fuzz = (FUZZ_DATA *)ptr;
+ curl_off_t nread;
+
+ /* If no upload data has been specified, then return an error code. */
+ if(fuzz->upload1_data_len == 0) {
+ /* No data to upload */
+ return CURL_READFUNC_ABORT;
+ }
+
+ /* Send the upload data. */
+ memcpy(buffer,
+ fuzz->upload1_data,
+ fuzz->upload1_data_len);
+
+ return fuzz->upload1_data_len;
+}
+
+/**
* TLV access function - gets the first TLV from a data stream.
*/
int fuzz_get_first_tlv(FUZZ_DATA *fuzz,
@@ -278,14 +331,9 @@ int fuzz_get_tlv_comn(FUZZ_DATA *fuzz,
int fuzz_parse_tlv(FUZZ_DATA *fuzz, TLV *tlv)
{
int rc;
+ char *tmp;
switch(tlv->type) {
- case TLV_TYPE_URL:
- FCHECK(fuzz->url == NULL);
- fuzz->url = fuzz_tlv_to_string(tlv);
- FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_URL, fuzz->url));
- break;
-
case TLV_TYPE_RESPONSE1:
/* The pointers in the TLV will always be valid as long as the fuzz data
is in scope, which is the entirety of this file. */
@@ -293,24 +341,42 @@ int fuzz_parse_tlv(FUZZ_DATA *fuzz, TLV *tlv)
fuzz->rsp1_data_len = tlv->length;
break;
- case TLV_TYPE_USERNAME:
- FCHECK(fuzz->username == NULL);
- fuzz->username = fuzz_tlv_to_string(tlv);
- FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_USERNAME, fuzz->username));
+ case TLV_TYPE_UPLOAD1:
+ /* The pointers in the TLV will always be valid as long as the fuzz data
+ is in scope, which is the entirety of this file. */
+ fuzz->upload1_data = tlv->value;
+ fuzz->upload1_data_len = tlv->length;
+
+ curl_easy_setopt(fuzz->easy, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(fuzz->easy,
+ CURLOPT_INFILESIZE_LARGE,
+ (curl_off_t)fuzz->upload1_data_len);
break;
- case TLV_TYPE_PASSWORD:
- FCHECK(fuzz->password == NULL);
- fuzz->password = fuzz_tlv_to_string(tlv);
- FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_PASSWORD, fuzz->password));
+ case TLV_TYPE_HEADER:
+ tmp = fuzz_tlv_to_string(tlv);
+ fuzz->header_list = curl_slist_append(fuzz->header_list, tmp);
+ fuzz_free((void **)&tmp);
break;
- case TLV_TYPE_POSTFIELDS:
- FCHECK(fuzz->postfields == NULL);
- fuzz->postfields = fuzz_tlv_to_string(tlv);
- FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_POSTFIELDS, fuzz->postfields));
+ case TLV_TYPE_MAIL_RECIPIENT:
+ tmp = fuzz_tlv_to_string(tlv);
+ fuzz->mail_recipients_list =
+ curl_slist_append(fuzz->mail_recipients_list, tmp);
+ fuzz_free((void **)&tmp);
break;
+ /* Define a set of singleton TLVs - they can only have their value set once
+ and all follow the same pattern. */
+ FSINGLETONTLV(TLV_TYPE_URL, url, CURLOPT_URL);
+ FSINGLETONTLV(TLV_TYPE_USERNAME, username, CURLOPT_USERNAME);
+ FSINGLETONTLV(TLV_TYPE_PASSWORD, password, CURLOPT_PASSWORD);
+ FSINGLETONTLV(TLV_TYPE_POSTFIELDS, postfields, CURLOPT_POSTFIELDS);
+ FSINGLETONTLV(TLV_TYPE_COOKIE, cookie, CURLOPT_COOKIE);
+ FSINGLETONTLV(TLV_TYPE_RANGE, range, CURLOPT_RANGE);
+ FSINGLETONTLV(TLV_TYPE_CUSTOMREQUEST, customrequest, CURLOPT_CUSTOMREQUEST);
+ FSINGLETONTLV(TLV_TYPE_MAIL_FROM, mail_from, CURLOPT_MAIL_FROM);
+
default:
/* The fuzzer generates lots of unknown TLVs, so don't do anything if
the TLV isn't known. */