Add XML fuzzers to libexpat upstream. (#308)
This commit is contained in:
parent
e3d6578214
commit
29eddcae5f
@ -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
|
||||
#
|
||||
|
59
expat/fuzz/xml_parse_fuzzer.c
Normal file
59
expat/fuzz/xml_parse_fuzzer.c
Normal 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;
|
||||
}
|
63
expat/fuzz/xml_parsebuffer_fuzzer.c
Normal file
63
expat/fuzz/xml_parsebuffer_fuzzer.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user