Преглед на файлове

CMake: Add ENABLE_FUZZING and "afl" target

Max Bruckner преди 8 години
родител
ревизия
0e0cd5bae5
променени са 17 файла, в които са добавени 435 реда и са изтрити 1 реда
  1. 1 1
      CMakeLists.txt
  2. 1 0
      fuzzing/.gitignore
  3. 21 0
      fuzzing/CMakeLists.txt
  4. 117 0
      fuzzing/afl.c
  5. 9 0
      fuzzing/afl.sh
  6. 22 0
      fuzzing/inputs/test1
  7. 1 0
      fuzzing/inputs/test10
  8. 8 0
      fuzzing/inputs/test11
  9. 11 0
      fuzzing/inputs/test2
  10. 26 0
      fuzzing/inputs/test3
  11. 88 0
      fuzzing/inputs/test4
  12. 27 0
      fuzzing/inputs/test5
  13. 16 0
      fuzzing/inputs/test6
  14. 22 0
      fuzzing/inputs/test7
  15. 13 0
      fuzzing/inputs/test8
  16. 5 0
      fuzzing/inputs/test9
  17. 47 0
      fuzzing/json.dict

+ 1 - 1
CMakeLists.txt

@@ -1,7 +1,7 @@
 set(CMAKE_LEGACY_CYGWIN_WIN32 0)
 cmake_minimum_required(VERSION 2.8)
 
-subdirs(tests)
+subdirs(tests fuzzing)
 
 include(GNUInstallDirs)
 

+ 1 - 0
fuzzing/.gitignore

@@ -0,0 +1 @@
+afl-build

+ 21 - 0
fuzzing/CMakeLists.txt

@@ -0,0 +1,21 @@
+option(ENABLE_FUZZING "Create executables and targets for fuzzing cJSON with afl." Off)
+if (ENABLE_FUZZING)
+    find_program(AFL_FUZZ afl-fuzz)
+    if ("${AFL_FUZZ}" MATCHES "AFL_FUZZ-NOTFOUND")
+        message(FATAL_ERROR "Couldn't find afl-fuzz.")
+    endif()
+
+
+    add_executable(afl-main afl.c)
+    target_link_libraries(afl-main "${CJSON_LIB}")
+
+    if (NOT ENABLE_SANITIZERS)
+        message(FATAL_ERROR "Enable sanitizers with -DENABLE_SANITIZERS=On to do fuzzing.")
+    endif()
+
+    add_custom_target(afl
+        COMMAND "${AFL_FUZZ}" -i "${CMAKE_CURRENT_SOURCE_DIR}/inputs" -o "${CMAKE_CURRENT_BINARY_DIR}/findings" -x "${CMAKE_CURRENT_SOURCE_DIR}/json.dict" -- "${CMAKE_CURRENT_BINARY_DIR}/afl-main" "@@"
+        DEPENDS afl-main)
+
+
+endif()

+ 117 - 0
fuzzing/afl.c

@@ -0,0 +1,117 @@
+/*
+  Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../cJSON.h"
+
+static char *read_file(const char *filename)
+{
+    FILE *file = NULL;
+    long length = 0;
+    char *content = NULL;
+    size_t read_chars = 0;
+
+    /* open in read binary mode */
+    file = fopen(filename, "rb");
+    if (file == NULL)
+    {
+        goto cleanup;
+    }
+
+    /* get the length */
+    if (fseek(file, 0, SEEK_END) != 0)
+    {
+        goto cleanup;
+    }
+    length = ftell(file);
+    if (length < 0)
+    {
+        goto cleanup;
+    }
+    if (fseek(file, 0, SEEK_SET) != 0)
+    {
+        goto cleanup;
+    }
+
+    /* allocate content buffer */
+    content = (char*)malloc((size_t)length + sizeof('\0'));
+    if (content == NULL)
+    {
+        goto cleanup;
+    }
+
+    /* read the file into memory */
+    read_chars = fread(content, sizeof(char), (size_t)length, file);
+    if ((long)read_chars != length)
+    {
+        free(content);
+        content = NULL;
+        goto cleanup;
+    }
+    content[read_chars] = '\0';
+
+
+cleanup:
+    if (file != NULL)
+    {
+        fclose(file);
+    }
+
+    return content;
+}
+
+int main(int argc, char** argv)
+{
+    const char *filename = NULL;
+    cJSON *item = NULL;
+    char *json = NULL;
+
+    if (argc < 2)
+    {
+        printf("Usage:\n");
+        printf("%s input_file\n", argv[0]);
+        printf("\t input_file: file containing the test data");
+    }
+
+    filename = argv[1];
+
+    json = read_file(filename);
+    item = cJSON_Parse(json);
+    if (item == NULL)
+    {
+        goto cleanup;
+    }
+
+cleanup:
+    if (item != NULL)
+    {
+        cJSON_Delete(item);
+    }
+    if (json != NULL)
+    {
+        free(json);
+    }
+
+    return EXIT_SUCCESS;
+}

+ 9 - 0
fuzzing/afl.sh

@@ -0,0 +1,9 @@
+#!/bin/bash
+
+mkdir -p afl-build || exit 1
+cd afl-build || exit 1
+#cleanup
+rm -r -- *
+
+CC=afl-gcc cmake ../.. -DENABLE_FUZZING=On -DENABLE_SANITIZERS=On -DBUILD_SHARED_LIBS=Off
+make afl

+ 22 - 0
fuzzing/inputs/test1

@@ -0,0 +1,22 @@
+{
+    "glossary": {
+        "title": "example glossary",
+		"GlossDiv": {
+            "title": "S",
+			"GlossList": {
+                "GlossEntry": {
+                    "ID": "SGML",
+					"SortAs": "SGML",
+					"GlossTerm": "Standard Generalized Markup Language",
+					"Acronym": "SGML",
+					"Abbrev": "ISO 8879:1986",
+					"GlossDef": {
+                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
+						"GlossSeeAlso": ["GML", "XML"]
+                    },
+					"GlossSee": "markup"
+                }
+            }
+        }
+    }
+}

+ 1 - 0
fuzzing/inputs/test10

@@ -0,0 +1 @@
+["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]

+ 8 - 0
fuzzing/inputs/test11

@@ -0,0 +1,8 @@
+{
+"name": "Jack (\"Bee\") Nimble", 
+"format": {"type":       "rect", 
+"width":      1920, 
+"height":     1080, 
+"interlace":  false,"frame rate": 24
+}
+}

+ 11 - 0
fuzzing/inputs/test2

@@ -0,0 +1,11 @@
+{"menu": {
+  "id": "file",
+  "value": "File",
+  "popup": {
+    "menuitem": [
+      {"value": "New", "onclick": "CreateNewDoc()"},
+      {"value": "Open", "onclick": "OpenDoc()"},
+      {"value": "Close", "onclick": "CloseDoc()"}
+    ]
+  }
+}}

+ 26 - 0
fuzzing/inputs/test3

@@ -0,0 +1,26 @@
+{"widget": {
+    "debug": "on",
+    "window": {
+        "title": "Sample Konfabulator Widget",
+        "name": "main_window",
+        "width": 500,
+        "height": 500
+    },
+    "image": { 
+        "src": "Images/Sun.png",
+        "name": "sun1",
+        "hOffset": 250,
+        "vOffset": 250,
+        "alignment": "center"
+    },
+    "text": {
+        "data": "Click Here",
+        "size": 36,
+        "style": "bold",
+        "name": "text1",
+        "hOffset": 250,
+        "vOffset": 100,
+        "alignment": "center",
+        "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
+    }
+}}    

+ 88 - 0
fuzzing/inputs/test4

@@ -0,0 +1,88 @@
+{"web-app": {
+  "servlet": [   
+    {
+      "servlet-name": "cofaxCDS",
+      "servlet-class": "org.cofax.cds.CDSServlet",
+      "init-param": {
+        "configGlossary:installationAt": "Philadelphia, PA",
+        "configGlossary:adminEmail": "ksm@pobox.com",
+        "configGlossary:poweredBy": "Cofax",
+        "configGlossary:poweredByIcon": "/images/cofax.gif",
+        "configGlossary:staticPath": "/content/static",
+        "templateProcessorClass": "org.cofax.WysiwygTemplate",
+        "templateLoaderClass": "org.cofax.FilesTemplateLoader",
+        "templatePath": "templates",
+        "templateOverridePath": "",
+        "defaultListTemplate": "listTemplate.htm",
+        "defaultFileTemplate": "articleTemplate.htm",
+        "useJSP": false,
+        "jspListTemplate": "listTemplate.jsp",
+        "jspFileTemplate": "articleTemplate.jsp",
+        "cachePackageTagsTrack": 200,
+        "cachePackageTagsStore": 200,
+        "cachePackageTagsRefresh": 60,
+        "cacheTemplatesTrack": 100,
+        "cacheTemplatesStore": 50,
+        "cacheTemplatesRefresh": 15,
+        "cachePagesTrack": 200,
+        "cachePagesStore": 100,
+        "cachePagesRefresh": 10,
+        "cachePagesDirtyRead": 10,
+        "searchEngineListTemplate": "forSearchEnginesList.htm",
+        "searchEngineFileTemplate": "forSearchEngines.htm",
+        "searchEngineRobotsDb": "WEB-INF/robots.db",
+        "useDataStore": true,
+        "dataStoreClass": "org.cofax.SqlDataStore",
+        "redirectionClass": "org.cofax.SqlRedirection",
+        "dataStoreName": "cofax",
+        "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver",
+        "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon",
+        "dataStoreUser": "sa",
+        "dataStorePassword": "dataStoreTestQuery",
+        "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';",
+        "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log",
+        "dataStoreInitConns": 10,
+        "dataStoreMaxConns": 100,
+        "dataStoreConnUsageLimit": 100,
+        "dataStoreLogLevel": "debug",
+        "maxUrlLength": 500}},
+    {
+      "servlet-name": "cofaxEmail",
+      "servlet-class": "org.cofax.cds.EmailServlet",
+      "init-param": {
+      "mailHost": "mail1",
+      "mailHostOverride": "mail2"}},
+    {
+      "servlet-name": "cofaxAdmin",
+      "servlet-class": "org.cofax.cds.AdminServlet"},
+ 
+    {
+      "servlet-name": "fileServlet",
+      "servlet-class": "org.cofax.cds.FileServlet"},
+    {
+      "servlet-name": "cofaxTools",
+      "servlet-class": "org.cofax.cms.CofaxToolsServlet",
+      "init-param": {
+        "templatePath": "toolstemplates/",
+        "log": 1,
+        "logLocation": "/usr/local/tomcat/logs/CofaxTools.log",
+        "logMaxSize": "",
+        "dataLog": 1,
+        "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log",
+        "dataLogMaxSize": "",
+        "removePageCache": "/content/admin/remove?cache=pages&id=",
+        "removeTemplateCache": "/content/admin/remove?cache=templates&id=",
+        "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder",
+        "lookInContext": 1,
+        "adminGroupID": 4,
+        "betaServer": true}}],
+  "servlet-mapping": {
+    "cofaxCDS": "/",
+    "cofaxEmail": "/cofaxutil/aemail/*",
+    "cofaxAdmin": "/admin/*",
+    "fileServlet": "/static/*",
+    "cofaxTools": "/tools/*"},
+ 
+  "taglib": {
+    "taglib-uri": "cofax.tld",
+    "taglib-location": "/WEB-INF/tlds/cofax.tld"}}}

+ 27 - 0
fuzzing/inputs/test5

@@ -0,0 +1,27 @@
+{"menu": {
+    "header": "SVG Viewer",
+    "items": [
+        {"id": "Open"},
+        {"id": "OpenNew", "label": "Open New"},
+        null,
+        {"id": "ZoomIn", "label": "Zoom In"},
+        {"id": "ZoomOut", "label": "Zoom Out"},
+        {"id": "OriginalView", "label": "Original View"},
+        null,
+        {"id": "Quality"},
+        {"id": "Pause"},
+        {"id": "Mute"},
+        null,
+        {"id": "Find", "label": "Find..."},
+        {"id": "FindAgain", "label": "Find Again"},
+        {"id": "Copy"},
+        {"id": "CopyAgain", "label": "Copy Again"},
+        {"id": "CopySVG", "label": "Copy SVG"},
+        {"id": "ViewSVG", "label": "View SVG"},
+        {"id": "ViewSource", "label": "View Source"},
+        {"id": "SaveAs", "label": "Save As"},
+        null,
+        {"id": "Help"},
+        {"id": "About", "label": "About Adobe CVG Viewer..."}
+    ]
+}}

+ 16 - 0
fuzzing/inputs/test6

@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+    <html>
+    <head>
+      <meta name="viewport" content="width=device-width, initial-scale=1">
+      <style type="text/css">
+        html, body, iframe { margin: 0; padding: 0; height: 100%; }
+        iframe { display: block; width: 100%; border: none; }
+      </style>
+    <title>Application Error</title>
+    </head>
+    <body>
+      <iframe src="//s3.amazonaws.com/heroku_pages/error.html">
+        <p>Application Error</p>
+      </iframe>
+    </body>
+    </html>

+ 22 - 0
fuzzing/inputs/test7

@@ -0,0 +1,22 @@
+[
+	 {
+	 "precision": "zip",
+	 "Latitude":  37.7668,
+	 "Longitude": -122.3959,
+	 "Address":   "",
+	 "City":      "SAN FRANCISCO",
+	 "State":     "CA",
+	 "Zip":       "94107",
+	 "Country":   "US"
+	 },
+	 {
+	 "precision": "zip",
+	 "Latitude":  37.371991,
+	 "Longitude": -122.026020,
+	 "Address":   "",
+	 "City":      "SUNNYVALE",
+	 "State":     "CA",
+	 "Zip":       "94085",
+	 "Country":   "US"
+	 }
+	 ]

+ 13 - 0
fuzzing/inputs/test8

@@ -0,0 +1,13 @@
+{
+		"Image": {
+			"Width":  800,
+			"Height": 600,
+			"Title":  "View from 15th Floor",
+			"Thumbnail": {
+				"Url":    "http:/*www.example.com/image/481989943",
+				"Height": 125,
+				"Width":  "100"
+			},
+			"IDs": [116, 943, 234, 38793]
+		}
+	}

+ 5 - 0
fuzzing/inputs/test9

@@ -0,0 +1,5 @@
+[
+    [0, -1, 0],
+    [1, 0, 0],
+    [0, 0, 1]
+	]

+ 47 - 0
fuzzing/json.dict

@@ -0,0 +1,47 @@
+#
+# AFL dictionary for JSON
+# -----------------------------
+#
+
+object_start="{"
+object_end="}"
+object_empty="{}"
+object_one_element="{\"one\":1}"
+object_two_elements="{\"1\":1,\"2\":2}"
+object_separator=":"
+
+array_start="["
+array_end="]"
+array_empty="[]"
+array_one_element="[1]"
+array_two_elements="[1,2]"
+
+separator=","
+
+escape_sequence_b="\\b"
+escape_sequence_f="\\f"
+escape_sequence_n="\\n"
+escape_sequence_r="\\r"
+escape_sequence_t="\\t"
+escape_sequence_quote="\\\""
+escape_sequence_backslash="\\\\"
+escapce_sequence_slash="\\/"
+escpae_sequence_utf16_base="\\u"
+escape_sequence_utf16="\\u12ab"
+
+number_integer="1"
+number_double="1.0"
+number_negative_integer="-1"
+number_negative_double="-1.0"
+number_engineering1="1e1"
+number_engineering2="1e-1"
+number_positive_integer="+1"
+number_positive_double="+1.0"
+number_e="e"
+number_plus="+"
+number_minus="-"
+number_separator="."
+
+null="null"
+true="true"
+false="false"