From 0e0cd5bae53daf71a420abd8501861b2d12ecd03 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Fri, 17 Feb 2017 15:48:50 +0100 Subject: [PATCH 1/6] CMake: Add ENABLE_FUZZING and "afl" target --- CMakeLists.txt | 2 +- fuzzing/.gitignore | 1 + fuzzing/CMakeLists.txt | 21 ++++++++ fuzzing/afl.c | 117 +++++++++++++++++++++++++++++++++++++++++ fuzzing/afl.sh | 9 ++++ fuzzing/inputs/test1 | 22 ++++++++ fuzzing/inputs/test10 | 1 + fuzzing/inputs/test11 | 8 +++ fuzzing/inputs/test2 | 11 ++++ fuzzing/inputs/test3 | 26 +++++++++ fuzzing/inputs/test4 | 88 +++++++++++++++++++++++++++++++ fuzzing/inputs/test5 | 27 ++++++++++ fuzzing/inputs/test6 | 16 ++++++ fuzzing/inputs/test7 | 22 ++++++++ fuzzing/inputs/test8 | 13 +++++ fuzzing/inputs/test9 | 5 ++ fuzzing/json.dict | 47 +++++++++++++++++ 17 files changed, 435 insertions(+), 1 deletion(-) create mode 100644 fuzzing/.gitignore create mode 100644 fuzzing/CMakeLists.txt create mode 100644 fuzzing/afl.c create mode 100755 fuzzing/afl.sh create mode 100644 fuzzing/inputs/test1 create mode 100644 fuzzing/inputs/test10 create mode 100644 fuzzing/inputs/test11 create mode 100644 fuzzing/inputs/test2 create mode 100644 fuzzing/inputs/test3 create mode 100644 fuzzing/inputs/test4 create mode 100644 fuzzing/inputs/test5 create mode 100644 fuzzing/inputs/test6 create mode 100644 fuzzing/inputs/test7 create mode 100644 fuzzing/inputs/test8 create mode 100644 fuzzing/inputs/test9 create mode 100644 fuzzing/json.dict diff --git a/CMakeLists.txt b/CMakeLists.txt index e7f2f7e..de01b79 100644 --- a/CMakeLists.txt +++ b/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) diff --git a/fuzzing/.gitignore b/fuzzing/.gitignore new file mode 100644 index 0000000..c82a262 --- /dev/null +++ b/fuzzing/.gitignore @@ -0,0 +1 @@ +afl-build diff --git a/fuzzing/CMakeLists.txt b/fuzzing/CMakeLists.txt new file mode 100644 index 0000000..d95be85 --- /dev/null +++ b/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() diff --git a/fuzzing/afl.c b/fuzzing/afl.c new file mode 100644 index 0000000..28c7e40 --- /dev/null +++ b/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 +#include + +#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; +} diff --git a/fuzzing/afl.sh b/fuzzing/afl.sh new file mode 100755 index 0000000..64b60a3 --- /dev/null +++ b/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 diff --git a/fuzzing/inputs/test1 b/fuzzing/inputs/test1 new file mode 100644 index 0000000..eacfbf5 --- /dev/null +++ b/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" + } + } + } + } +} diff --git a/fuzzing/inputs/test10 b/fuzzing/inputs/test10 new file mode 100644 index 0000000..d19eb8b --- /dev/null +++ b/fuzzing/inputs/test10 @@ -0,0 +1 @@ +["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] diff --git a/fuzzing/inputs/test11 b/fuzzing/inputs/test11 new file mode 100644 index 0000000..eaf43e6 --- /dev/null +++ b/fuzzing/inputs/test11 @@ -0,0 +1,8 @@ +{ +"name": "Jack (\"Bee\") Nimble", +"format": {"type": "rect", +"width": 1920, +"height": 1080, +"interlace": false,"frame rate": 24 +} +} diff --git a/fuzzing/inputs/test2 b/fuzzing/inputs/test2 new file mode 100644 index 0000000..5600991 --- /dev/null +++ b/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()"} + ] + } +}} diff --git a/fuzzing/inputs/test3 b/fuzzing/inputs/test3 new file mode 100644 index 0000000..5662b37 --- /dev/null +++ b/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;" + } +}} \ No newline at end of file diff --git a/fuzzing/inputs/test4 b/fuzzing/inputs/test4 new file mode 100644 index 0000000..d540b57 --- /dev/null +++ b/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"}}} \ No newline at end of file diff --git a/fuzzing/inputs/test5 b/fuzzing/inputs/test5 new file mode 100644 index 0000000..49980ca --- /dev/null +++ b/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..."} + ] +}} diff --git a/fuzzing/inputs/test6 b/fuzzing/inputs/test6 new file mode 100644 index 0000000..d5cb28f --- /dev/null +++ b/fuzzing/inputs/test6 @@ -0,0 +1,16 @@ + + + + + + Application Error + + + + + \ No newline at end of file diff --git a/fuzzing/inputs/test7 b/fuzzing/inputs/test7 new file mode 100644 index 0000000..3308536 --- /dev/null +++ b/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" + } + ] diff --git a/fuzzing/inputs/test8 b/fuzzing/inputs/test8 new file mode 100644 index 0000000..4b1f5b9 --- /dev/null +++ b/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] + } + } diff --git a/fuzzing/inputs/test9 b/fuzzing/inputs/test9 new file mode 100644 index 0000000..2a939b9 --- /dev/null +++ b/fuzzing/inputs/test9 @@ -0,0 +1,5 @@ +[ + [0, -1, 0], + [1, 0, 0], + [0, 0, 1] + ] diff --git a/fuzzing/json.dict b/fuzzing/json.dict new file mode 100644 index 0000000..ac9c08c --- /dev/null +++ b/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" From 4785070ad33b211230f24b5bd28628b560174629 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Sat, 18 Feb 2017 02:07:12 +0100 Subject: [PATCH 2/6] fuzzing: Fuzz printing as well. With one big limitation: It can only be fuzzed with what has been parsed by the library beforehand. --- fuzzing/CMakeLists.txt | 9 +++++++-- fuzzing/afl.c | 32 ++++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/fuzzing/CMakeLists.txt b/fuzzing/CMakeLists.txt index d95be85..d39a652 100644 --- a/fuzzing/CMakeLists.txt +++ b/fuzzing/CMakeLists.txt @@ -5,7 +5,6 @@ if (ENABLE_FUZZING) message(FATAL_ERROR "Couldn't find afl-fuzz.") endif() - add_executable(afl-main afl.c) target_link_libraries(afl-main "${CJSON_LIB}") @@ -13,8 +12,14 @@ if (ENABLE_FUZZING) message(FATAL_ERROR "Enable sanitizers with -DENABLE_SANITIZERS=On to do fuzzing.") endif() + option(ENABLE_FUZZING_PRINT "Fuzz printing functions together with parser." On) + set(fuzz_print_parameter "no") + if (ENABLE_FUZZING_PRINT) + set(fuzz_print_parameter "yes") + 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" "@@" + 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" "@@" "${fuzz_print_parameter}" DEPENDS afl-main) diff --git a/fuzzing/afl.c b/fuzzing/afl.c index 28c7e40..f2452de 100644 --- a/fuzzing/afl.c +++ b/fuzzing/afl.c @@ -22,6 +22,7 @@ #include #include +#include #include "../cJSON.h" @@ -86,23 +87,42 @@ int main(int argc, char** argv) const char *filename = NULL; cJSON *item = NULL; char *json = NULL; + int status = EXIT_SUCCESS; + char *printed_json = NULL; - if (argc < 2) + if ((argc < 2) || (argc > 3)) { printf("Usage:\n"); - printf("%s input_file\n", argv[0]); - printf("\t input_file: file containing the test data"); + printf("%s input_file [enable_printing]\n", argv[0]); + printf("\t input_file: file containing the test data\n"); + printf("\t enable_printing: print after parsing, 'yes' or 'no', defaults to 'no'\n"); } filename = argv[1]; json = read_file(filename); + if (json == NULL) + { + status = EXIT_FAILURE; + goto cleanup; + } item = cJSON_Parse(json); if (item == NULL) { goto cleanup; } + if ((argc == 3) && (strncmp(argv[2], "yes", 3) == 0)) + { + printed_json = cJSON_Print(item); + if (printed_json == NULL) + { + status = EXIT_FAILURE; + goto cleanup; + } + printf("%s\n", printed_json); + } + cleanup: if (item != NULL) { @@ -112,6 +132,10 @@ cleanup: { free(json); } + if (printed_json != NULL) + { + free(printed_json); + } - return EXIT_SUCCESS; + return status; } From c5a09a32a9ca1ca6c614a2b61db69350beeedadc Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Sat, 18 Feb 2017 02:31:42 +0100 Subject: [PATCH 3/6] fuzzing: Fuzz different print methods This is achieved by encoding the type of function used in the first two bytes. First byte: b: buffered Second byte: f: formatted --- fuzzing/afl.c | 28 +++++++++++++++++++++++++--- fuzzing/inputs/test1 | 2 +- fuzzing/inputs/test10 | 2 +- fuzzing/inputs/test11 | 2 +- fuzzing/inputs/test2 | 2 +- fuzzing/inputs/test3 | 4 ++-- fuzzing/inputs/test3.bu | 26 ++++++++++++++++++++++++++ fuzzing/inputs/test3.uf | 26 ++++++++++++++++++++++++++ fuzzing/inputs/test3.uu | 26 ++++++++++++++++++++++++++ fuzzing/inputs/test4 | 4 ++-- fuzzing/inputs/test5 | 2 +- fuzzing/inputs/test6 | 4 ++-- fuzzing/inputs/test7 | 2 +- fuzzing/inputs/test8 | 2 +- fuzzing/inputs/test9 | 2 +- 15 files changed, 117 insertions(+), 17 deletions(-) create mode 100644 fuzzing/inputs/test3.bu create mode 100644 fuzzing/inputs/test3.uf create mode 100644 fuzzing/inputs/test3.uu diff --git a/fuzzing/afl.c b/fuzzing/afl.c index f2452de..59bbca7 100644 --- a/fuzzing/afl.c +++ b/fuzzing/afl.c @@ -101,12 +101,12 @@ int main(int argc, char** argv) filename = argv[1]; json = read_file(filename); - if (json == NULL) + if ((json == NULL) || (json[0] == '\0') || (json[1] == '\0')) { status = EXIT_FAILURE; goto cleanup; } - item = cJSON_Parse(json); + item = cJSON_Parse(json + 2); if (item == NULL) { goto cleanup; @@ -114,7 +114,29 @@ int main(int argc, char** argv) if ((argc == 3) && (strncmp(argv[2], "yes", 3) == 0)) { - printed_json = cJSON_Print(item); + int do_format = 0; + if (json[1] == 'f') + { + do_format = 1; + } + + if (json[0] == 'b') + { + /* buffered printing */ + printed_json = cJSON_PrintBuffered(item, 1, do_format); + } + else + { + /* unbuffered printing */ + if (do_format) + { + printed_json = cJSON_Print(item); + } + else + { + printed_json = cJSON_PrintUnformatted(item); + } + } if (printed_json == NULL) { status = EXIT_FAILURE; diff --git a/fuzzing/inputs/test1 b/fuzzing/inputs/test1 index eacfbf5..6a0c0d7 100644 --- a/fuzzing/inputs/test1 +++ b/fuzzing/inputs/test1 @@ -1,4 +1,4 @@ -{ +bf{ "glossary": { "title": "example glossary", "GlossDiv": { diff --git a/fuzzing/inputs/test10 b/fuzzing/inputs/test10 index d19eb8b..01e9a82 100644 --- a/fuzzing/inputs/test10 +++ b/fuzzing/inputs/test10 @@ -1 +1 @@ -["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] +bf["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] diff --git a/fuzzing/inputs/test11 b/fuzzing/inputs/test11 index eaf43e6..818c6e0 100644 --- a/fuzzing/inputs/test11 +++ b/fuzzing/inputs/test11 @@ -1,4 +1,4 @@ -{ +bf{ "name": "Jack (\"Bee\") Nimble", "format": {"type": "rect", "width": 1920, diff --git a/fuzzing/inputs/test2 b/fuzzing/inputs/test2 index 5600991..3fdf8cb 100644 --- a/fuzzing/inputs/test2 +++ b/fuzzing/inputs/test2 @@ -1,4 +1,4 @@ -{"menu": { +bf{"menu": { "id": "file", "value": "File", "popup": { diff --git a/fuzzing/inputs/test3 b/fuzzing/inputs/test3 index 5662b37..7143163 100644 --- a/fuzzing/inputs/test3 +++ b/fuzzing/inputs/test3 @@ -1,4 +1,4 @@ -{"widget": { +bf{"widget": { "debug": "on", "window": { "title": "Sample Konfabulator Widget", @@ -23,4 +23,4 @@ "alignment": "center", "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" } -}} \ No newline at end of file +}} diff --git a/fuzzing/inputs/test3.bu b/fuzzing/inputs/test3.bu new file mode 100644 index 0000000..6fc93d3 --- /dev/null +++ b/fuzzing/inputs/test3.bu @@ -0,0 +1,26 @@ +bu{"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;" + } +}} diff --git a/fuzzing/inputs/test3.uf b/fuzzing/inputs/test3.uf new file mode 100644 index 0000000..d48df61 --- /dev/null +++ b/fuzzing/inputs/test3.uf @@ -0,0 +1,26 @@ +uf{"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;" + } +}} diff --git a/fuzzing/inputs/test3.uu b/fuzzing/inputs/test3.uu new file mode 100644 index 0000000..ad6ae54 --- /dev/null +++ b/fuzzing/inputs/test3.uu @@ -0,0 +1,26 @@ +uu{"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;" + } +}} diff --git a/fuzzing/inputs/test4 b/fuzzing/inputs/test4 index d540b57..e24ae9b 100644 --- a/fuzzing/inputs/test4 +++ b/fuzzing/inputs/test4 @@ -1,4 +1,4 @@ -{"web-app": { +bf{"web-app": { "servlet": [ { "servlet-name": "cofaxCDS", @@ -85,4 +85,4 @@ "taglib": { "taglib-uri": "cofax.tld", - "taglib-location": "/WEB-INF/tlds/cofax.tld"}}} \ No newline at end of file + "taglib-location": "/WEB-INF/tlds/cofax.tld"}}} diff --git a/fuzzing/inputs/test5 b/fuzzing/inputs/test5 index 49980ca..f6cc84e 100644 --- a/fuzzing/inputs/test5 +++ b/fuzzing/inputs/test5 @@ -1,4 +1,4 @@ -{"menu": { +bf{"menu": { "header": "SVG Viewer", "items": [ {"id": "Open"}, diff --git a/fuzzing/inputs/test6 b/fuzzing/inputs/test6 index d5cb28f..af27975 100644 --- a/fuzzing/inputs/test6 +++ b/fuzzing/inputs/test6 @@ -1,4 +1,4 @@ - +bf @@ -13,4 +13,4 @@

Application Error

- \ No newline at end of file + diff --git a/fuzzing/inputs/test7 b/fuzzing/inputs/test7 index 3308536..4a3c0b7 100644 --- a/fuzzing/inputs/test7 +++ b/fuzzing/inputs/test7 @@ -1,4 +1,4 @@ -[ +bf[ { "precision": "zip", "Latitude": 37.7668, diff --git a/fuzzing/inputs/test8 b/fuzzing/inputs/test8 index 4b1f5b9..3ffe570 100644 --- a/fuzzing/inputs/test8 +++ b/fuzzing/inputs/test8 @@ -1,4 +1,4 @@ -{ +bf{ "Image": { "Width": 800, "Height": 600, diff --git a/fuzzing/inputs/test9 b/fuzzing/inputs/test9 index 2a939b9..28c9033 100644 --- a/fuzzing/inputs/test9 +++ b/fuzzing/inputs/test9 @@ -1,4 +1,4 @@ -[ +bf[ [0, -1, 0], [1, 0, 0], [0, 0, 1] From ae4681b7871d2cc7fb159c67f5b1af3d887a5e3b Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Sat, 18 Feb 2017 02:46:36 +0100 Subject: [PATCH 4/6] fuzzing: use llvm source code instrumentation --- fuzzing/afl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzzing/afl.sh b/fuzzing/afl.sh index 64b60a3..8f0f02f 100755 --- a/fuzzing/afl.sh +++ b/fuzzing/afl.sh @@ -5,5 +5,5 @@ cd afl-build || exit 1 #cleanup rm -r -- * -CC=afl-gcc cmake ../.. -DENABLE_FUZZING=On -DENABLE_SANITIZERS=On -DBUILD_SHARED_LIBS=Off +CC=afl-clang-fast cmake ../.. -DENABLE_FUZZING=On -DENABLE_SANITIZERS=On -DBUILD_SHARED_LIBS=Off make afl From da551c753f49ded690d60d5dbe81ad35c4eaefb8 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Sat, 18 Feb 2017 02:52:38 +0100 Subject: [PATCH 5/6] fuzzing: Speed up afl using persistent mode (in proccess fuzzing) --- fuzzing/CMakeLists.txt | 2 ++ fuzzing/afl.c | 14 +++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/fuzzing/CMakeLists.txt b/fuzzing/CMakeLists.txt index d39a652..fdd7126 100644 --- a/fuzzing/CMakeLists.txt +++ b/fuzzing/CMakeLists.txt @@ -18,6 +18,8 @@ if (ENABLE_FUZZING) set(fuzz_print_parameter "yes") endif() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error") + 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" "@@" "${fuzz_print_parameter}" DEPENDS afl-main) diff --git a/fuzzing/afl.c b/fuzzing/afl.c index 59bbca7..af5945d 100644 --- a/fuzzing/afl.c +++ b/fuzzing/afl.c @@ -87,7 +87,7 @@ int main(int argc, char** argv) const char *filename = NULL; cJSON *item = NULL; char *json = NULL; - int status = EXIT_SUCCESS; + int status; char *printed_json = NULL; if ((argc < 2) || (argc > 3)) @@ -100,6 +100,12 @@ int main(int argc, char** argv) filename = argv[1]; +#if __AFL_HAVE_MANUAL_CONTROL + while (__AFL_LOOP(1000)) + { +#endif + status = EXIT_SUCCESS; + json = read_file(filename); if ((json == NULL) || (json[0] == '\0') || (json[1] == '\0')) { @@ -149,15 +155,21 @@ cleanup: if (item != NULL) { cJSON_Delete(item); + item = NULL; } if (json != NULL) { free(json); + json = NULL; } if (printed_json != NULL) { free(printed_json); + printed_json = NULL; } +#if __AFL_HAVE_MANUAL_CONTROL + } +#endif return status; } From cf71f3d6277c16b47a506fbe5d1d01be417c19fc Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Sat, 18 Feb 2017 12:51:34 +0100 Subject: [PATCH 6/6] fuzzing: script to prepare linux kernel for afl --- fuzzing/afl-prepare-linux.sh | 5 +++++ 1 file changed, 5 insertions(+) create mode 100755 fuzzing/afl-prepare-linux.sh diff --git a/fuzzing/afl-prepare-linux.sh b/fuzzing/afl-prepare-linux.sh new file mode 100755 index 0000000..41c9b89 --- /dev/null +++ b/fuzzing/afl-prepare-linux.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +set -x +echo core | sudo tee /proc/sys/kernel/core_pattern +echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor