gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnurl] 176/256: ossfuzz: add some more handled CURL option


From: gnunet
Subject: [GNUnet-SVN] [gnurl] 176/256: ossfuzz: add some more handled CURL options
Date: Fri, 06 Oct 2017 19:44:27 +0200

This is an automated email from the git hooks/post-receive script.

ng0 pushed a commit to branch master
in repository gnurl.

commit 261da2a6685c0185283dbf72ce543e9fd81e9bd8
Author: Max Dymond <address@hidden>
AuthorDate: Sat Sep 2 22:40:01 2017 +0100

    ossfuzz: add some more handled CURL options
    
    Add support for HEADER, COOKIE, RANGE, CUSTOMREQUEST, MAIL_RECIPIENT,
    MAIL_FROM and uploading data.
---
 tests/fuzz/Makefile.am            |   2 +-
 tests/fuzz/curl_fuzz_data/test10  | Bin 0 -> 226 bytes
 tests/fuzz/curl_fuzz_data/test12  | Bin 0 -> 464 bytes
 tests/fuzz/curl_fuzz_data/test13  | Bin 0 -> 179 bytes
 tests/fuzz/curl_fuzz_data/test4   | Bin 0 -> 336 bytes
 tests/fuzz/curl_fuzz_data/test5   | Bin 0 -> 185 bytes
 tests/fuzz/curl_fuzz_data/test6   | Bin 0 -> 223 bytes
 tests/fuzz/curl_fuzz_data/test900 | Bin 0 -> 129 bytes
 tests/fuzz/curl_fuzzer.cc         | 106 +++++++++++++++++++++++++++++++-------
 tests/fuzz/curl_fuzzer.h          |  40 +++++++++++---
 tests/fuzz/generate_corpus.py     |  40 +++++++++++++-
 11 files changed, 160 insertions(+), 28 deletions(-)

diff --git a/tests/fuzz/Makefile.am b/tests/fuzz/Makefile.am
index b7968d3d4..3bd24dd66 100644
--- a/tests/fuzz/Makefile.am
+++ b/tests/fuzz/Makefile.am
@@ -50,7 +50,7 @@ LDADD = $(top_builddir)/lib/libcurl.la      \
 include Makefile.inc
 
 checksrc:
-       @PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.c
+       @PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.cc
 
 noinst_PROGRAMS = $(FUZZPROGS)
 noinst_LIBRARIES = $(FUZZLIBS)
diff --git a/tests/fuzz/curl_fuzz_data/test10 b/tests/fuzz/curl_fuzz_data/test10
new file mode 100644
index 000000000..af1ed53ca
Binary files /dev/null and b/tests/fuzz/curl_fuzz_data/test10 differ
diff --git a/tests/fuzz/curl_fuzz_data/test12 b/tests/fuzz/curl_fuzz_data/test12
new file mode 100644
index 000000000..9ad91dc07
Binary files /dev/null and b/tests/fuzz/curl_fuzz_data/test12 differ
diff --git a/tests/fuzz/curl_fuzz_data/test13 b/tests/fuzz/curl_fuzz_data/test13
new file mode 100644
index 000000000..448077dde
Binary files /dev/null and b/tests/fuzz/curl_fuzz_data/test13 differ
diff --git a/tests/fuzz/curl_fuzz_data/test4 b/tests/fuzz/curl_fuzz_data/test4
new file mode 100644
index 000000000..3fa395a29
Binary files /dev/null and b/tests/fuzz/curl_fuzz_data/test4 differ
diff --git a/tests/fuzz/curl_fuzz_data/test5 b/tests/fuzz/curl_fuzz_data/test5
new file mode 100644
index 000000000..bdaac4e66
Binary files /dev/null and b/tests/fuzz/curl_fuzz_data/test5 differ
diff --git a/tests/fuzz/curl_fuzz_data/test6 b/tests/fuzz/curl_fuzz_data/test6
new file mode 100644
index 000000000..98d9be216
Binary files /dev/null and b/tests/fuzz/curl_fuzz_data/test6 differ
diff --git a/tests/fuzz/curl_fuzz_data/test900 
b/tests/fuzz/curl_fuzz_data/test900
new file mode 100644
index 000000000..eecf0cbaf
Binary files /dev/null and b/tests/fuzz/curl_fuzz_data/test900 differ
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. */
diff --git a/tests/fuzz/curl_fuzzer.h b/tests/fuzz/curl_fuzzer.h
index 634160648..2dd3827d0 100644
--- a/tests/fuzz/curl_fuzzer.h
+++ b/tests/fuzz/curl_fuzzer.h
@@ -31,6 +31,13 @@
 #define TLV_TYPE_USERNAME               3
 #define TLV_TYPE_PASSWORD               4
 #define TLV_TYPE_POSTFIELDS             5
+#define TLV_TYPE_HEADER                 6
+#define TLV_TYPE_COOKIE                 7
+#define TLV_TYPE_UPLOAD1                8
+#define TLV_TYPE_RANGE                  9
+#define TLV_TYPE_CUSTOMREQUEST          10
+#define TLV_TYPE_MAIL_RECIPIENT         11
+#define TLV_TYPE_MAIL_FROM              12
 
 /**
  * TLV function return codes.
@@ -91,19 +98,29 @@ typedef struct fuzz_data
   /* Parser state */
   FUZZ_PARSE_STATE state;
 
-  /* Current URL. */
-  char *url;
-
   /* Response data and length */
   const uint8_t *rsp1_data;
   size_t rsp1_data_len;
 
-  /* Username and password */
+  /* Upload data and length; */
+  const uint8_t *upload1_data;
+  size_t upload1_data_len;
+
+  /* Singleton string fields. */
+  char *url;
   char *username;
   char *password;
-
-  /* Postfields */
   char *postfields;
+  char *cookie;
+  char *range;
+  char *customrequest;
+  char *mail_from;
+
+  /* List of headers */
+  struct curl_slist *header_list;
+
+  /* List of mail recipients */
+  struct curl_slist *mail_recipients_list;
 
 } FUZZ_DATA;
 
@@ -121,6 +138,10 @@ static curl_socket_t fuzz_open_socket(void *ptr,
 static int fuzz_sockopt_callback(void *ptr,
                                  curl_socket_t curlfd,
                                  curlsocktype purpose);
+static size_t fuzz_read_callback(char *buffer,
+                                 size_t size,
+                                 size_t nitems,
+                                 void *ptr);
 int fuzz_get_first_tlv(FUZZ_DATA *fuzz, TLV *tlv);
 int fuzz_get_next_tlv(FUZZ_DATA *fuzz, TLV *tlv);
 int fuzz_get_tlv_comn(FUZZ_DATA *fuzz, TLV *tlv);
@@ -146,3 +167,10 @@ char *fuzz_tlv_to_string(TLV *tlv);
             goto EXIT_LABEL;                                                   
\
           }                                                                    
\
         }
+
+#define FSINGLETONTLV(TLVNAME, FIELDNAME, OPTNAME)                             
\
+    case TLVNAME:                                                              
\
+      FCHECK(fuzz->FIELDNAME == NULL);                                         
\
+      fuzz->FIELDNAME = fuzz_tlv_to_string(tlv);                               
\
+      FTRY(curl_easy_setopt(fuzz->easy, OPTNAME, fuzz->FIELDNAME));            
\
+      break
\ No newline at end of file
diff --git a/tests/fuzz/generate_corpus.py b/tests/fuzz/generate_corpus.py
index 0bb2eda3c..04c799926 100755
--- a/tests/fuzz/generate_corpus.py
+++ b/tests/fuzz/generate_corpus.py
@@ -36,6 +36,27 @@ def generate_corpus(options):
         enc.maybe_write_string(enc.TYPE_USERNAME, options.username)
         enc.maybe_write_string(enc.TYPE_PASSWORD, options.password)
         enc.maybe_write_string(enc.TYPE_POSTFIELDS, options.postfields)
+        enc.maybe_write_string(enc.TYPE_COOKIE, options.cookie)
+        enc.maybe_write_string(enc.TYPE_RANGE, options.range)
+        enc.maybe_write_string(enc.TYPE_CUSTOMREQUEST, options.customrequest)
+        enc.maybe_write_string(enc.TYPE_MAIL_FROM, options.mailfrom)
+
+        # Write the first upload to the file.
+        if options.upload1:
+            enc.write_bytes(enc.TYPE_UPLOAD1, options.upload1.encode("utf-8"))
+        elif options.upload1file:
+            with open(options.upload1file, "rb") as g:
+                enc.write_bytes(enc.TYPE_UPLOAD1, g.read())
+
+        # Write an array of headers to the file.
+        if options.header:
+            for header in options.header:
+                enc.write_string(enc.TYPE_HEADER, header)
+
+        # Write an array of headers to the file.
+        if options.mailrecipient:
+            for mailrecipient in options.mailrecipient:
+                enc.write_string(enc.TYPE_MAIL_RECIPIENT, mailrecipient)
 
     return ScriptRC.SUCCESS
 
@@ -46,6 +67,13 @@ class TLVEncoder(object):
     TYPE_USERNAME = 3
     TYPE_PASSWORD = 4
     TYPE_POSTFIELDS = 5
+    TYPE_HEADER = 6
+    TYPE_COOKIE = 7
+    TYPE_UPLOAD1 = 8
+    TYPE_RANGE = 9
+    TYPE_CUSTOMREQUEST = 10
+    TYPE_MAIL_RECIPIENT = 11
+    TYPE_MAIL_FROM = 12
 
     def __init__(self, output):
         self.output = output
@@ -58,7 +86,7 @@ class TLVEncoder(object):
         self.write_tlv(tlv_type, len(bytedata), bytedata)
 
     def maybe_write_string(self, tlv_type, wstring):
-        if wstring:
+        if wstring is not None:
             self.write_string(tlv_type, wstring)
 
     def write_tlv(self, tlv_type, tlv_length, tlv_data=None):
@@ -84,12 +112,22 @@ def get_options():
     parser.add_argument("--username")
     parser.add_argument("--password")
     parser.add_argument("--postfields")
+    parser.add_argument("--header", action="append")
+    parser.add_argument("--cookie")
+    parser.add_argument("--range")
+    parser.add_argument("--customrequest")
+    parser.add_argument("--mailfrom")
+    parser.add_argument("--mailrecipient", action="append")
 
     rsp1 = parser.add_mutually_exclusive_group(required=True)
     rsp1.add_argument("--rsp1")
     rsp1.add_argument("--rsp1file")
     rsp1.add_argument("--rsp1test", type=int)
 
+    upload1 = parser.add_mutually_exclusive_group()
+    upload1.add_argument("--upload1")
+    upload1.add_argument("--upload1file")
+
     return parser.parse_args()
 
 

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]