Add XML fuzzers to libexpat upstream. (#308)

This commit is contained in:
Mitch Phillips 2019-08-28 03:57:57 -07:00 committed by Sebastian Pipping
parent e3d6578214
commit 29eddcae5f
3 changed files with 157 additions and 0 deletions

View File

@ -45,6 +45,7 @@ option(BUILD_examples "build the examples for expat library" ON)
option(BUILD_tests "build the tests for expat library" ON)
option(BUILD_shared "build a shared expat library" ON)
option(BUILD_doc "build man page for xmlwf" ${BUILD_doc_default})
option(BUILD_fuzzers "build fuzzers for the expat library" OFF)
option(USE_libbsd "utilize libbsd (for arc4random_buf)" OFF)
option(INSTALL "install expat files in cmake install target" ON)
set(XML_CONTEXT_BYTES 1024 CACHE STRING "Define to specify how much context to retain around the current parse point")
@ -324,6 +325,40 @@ if(BUILD_tests)
add_test(runtestspp tests/runtestspp)
endif(BUILD_tests)
if(BUILD_fuzzers)
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
message(SEND_ERROR
"Building fuzz targets without clang is not supported. Please set "
"-DCMAKE_C_COMPILER=clang.")
endif()
string(FIND "${CMAKE_EXE_LINKER_FLAGS}" "-fsanitize" sanitizer_present)
if(${sanitizer_present} EQUAL "-1")
message(WARNING
"There was no sanitizer present when building the fuzz targets. "
"This is likely in error - consider adding "
"-DCMAKE_C_FLAGS='-fsanitize=<sanitizer>' and "
"-DCMAKE_EXE_LINKER_FLAGS='-fsanitize=<sanitizer>' to your cmake "
"execution.")
endif()
set(encoding_types UTF-16 UTF-8 ISO-8859-1 US-ASCII UTF-16BE UTF-16LE)
set(fuzz_targets xml_parse_fuzzer xml_parsebuffer_fuzzer)
foreach(fuzz_target ${fuzz_targets})
foreach(encoding_type ${encoding_types})
set(target_name ${fuzz_target}_${encoding_type})
add_executable(${target_name} fuzz/${fuzz_target}.c ${expat_SRCS})
target_compile_definitions(${target_name}
PRIVATE ENCODING_FOR_FUZZING=${encoding_type})
target_compile_options(${target_name} PRIVATE -fsanitize=fuzzer-no-link)
target_link_options(${target_name} PRIVATE -fsanitize=fuzzer)
set_property(
TARGET ${target_name} PROPERTY RUNTIME_OUTPUT_DIRECTORY fuzz)
endforeach()
endforeach()
endif(BUILD_fuzzers)
#
# Summary
#

View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <assert.h>
#include <stdint.h>
#include "expat.h"
#include "siphash.h"
// Macros to convert preprocessor macros to string literals. See
// https://gcc.gnu.org/onlinedocs/gcc-3.4.3/cpp/Stringification.html
#define xstr(s) str(s)
#define str(s) #s
// The encoder type that we wish to fuzz should come from the compile-time
// definition `ENCODING_FOR_FUZZING`. This allows us to have a separate fuzzer
// binary for
#ifndef ENCODING_FOR_FUZZING
# error "ENCODING_FOR_FUZZING was not provided to this fuzz target."
#endif
// 16-byte determinstic hash key.
static unsigned char hash_key[16] = "FUZZING IS FUN!";
static void XMLCALL
start(void *userData, const XML_Char *name, const XML_Char **atts) {
}
static void XMLCALL
end(void *userData, const XML_Char *name) {
}
int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
XML_Parser p = XML_ParserCreate(xstr(ENCODING_FOR_FUZZING));
assert(p);
// Set the hash salt using siphash to generate a deterministic hash.
struct sipkey *key = sip_keyof(hash_key);
XML_SetHashSalt(p, (unsigned long)siphash24(data, size, key));
XML_SetElementHandler(p, start, end);
XML_Parse(p, (const XML_Char *)data, size, 0);
XML_Parse(p, (const XML_Char *)data, size, 1);
XML_ParserFree(p);
return 0;
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include "expat.h"
#include "siphash.h"
// Macros to convert preprocessor macros to string literals. See
// https://gcc.gnu.org/onlinedocs/gcc-3.4.3/cpp/Stringification.html
#define xstr(s) str(s)
#define str(s) #s
// The encoder type that we wish to fuzz should come from the compile-time
// definition `ENCODING_FOR_FUZZING`. This allows us to have a separate fuzzer
// binary for
#ifndef ENCODING_FOR_FUZZING
# error "ENCODING_FOR_FUZZING was not provided to this fuzz target."
#endif
// 16-byte determinstic hash key.
static unsigned char hash_key[16] = "FUZZING IS FUN!";
static void XMLCALL
start(void *userData, const XML_Char *name, const XML_Char **atts) {
}
static void XMLCALL
end(void *userData, const XML_Char *name) {
}
int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
XML_Parser p = XML_ParserCreate(xstr(ENCODING_FOR_FUZZING));
assert(p);
XML_SetElementHandler(p, start, end);
// Set the hash salt using siphash to generate a deterministic hash.
struct sipkey *key = sip_keyof(hash_key);
XML_SetHashSalt(p, (unsigned long)siphash24(data, size, key));
void *buf = XML_GetBuffer(p, size);
assert(buf);
memcpy(buf, data, size);
XML_ParseBuffer(p, size, size == 0);
XML_ParserFree(p);
return 0;
}