1*fd525a9cSAndroid Build Coastguard Worker // Copyright 2017 Google Inc. All rights reserved. 2*fd525a9cSAndroid Build Coastguard Worker // 3*fd525a9cSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*fd525a9cSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*fd525a9cSAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*fd525a9cSAndroid Build Coastguard Worker // 7*fd525a9cSAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 8*fd525a9cSAndroid Build Coastguard Worker // 9*fd525a9cSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*fd525a9cSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*fd525a9cSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*fd525a9cSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*fd525a9cSAndroid Build Coastguard Worker // limitations under the License. 14*fd525a9cSAndroid Build Coastguard Worker 15*fd525a9cSAndroid Build Coastguard Worker #ifndef SRC_LIBFUZZER_LIBFUZZER_MACRO_H_ 16*fd525a9cSAndroid Build Coastguard Worker #define SRC_LIBFUZZER_LIBFUZZER_MACRO_H_ 17*fd525a9cSAndroid Build Coastguard Worker 18*fd525a9cSAndroid Build Coastguard Worker #include <stddef.h> 19*fd525a9cSAndroid Build Coastguard Worker 20*fd525a9cSAndroid Build Coastguard Worker #include <cstdint> 21*fd525a9cSAndroid Build Coastguard Worker #include <functional> 22*fd525a9cSAndroid Build Coastguard Worker #include <type_traits> 23*fd525a9cSAndroid Build Coastguard Worker 24*fd525a9cSAndroid Build Coastguard Worker #include "port/protobuf.h" 25*fd525a9cSAndroid Build Coastguard Worker 26*fd525a9cSAndroid Build Coastguard Worker // Defines custom mutator, crossover and test functions using default 27*fd525a9cSAndroid Build Coastguard Worker // serialization format. Default is text. 28*fd525a9cSAndroid Build Coastguard Worker #define DEFINE_PROTO_FUZZER(arg) DEFINE_TEXT_PROTO_FUZZER(arg) 29*fd525a9cSAndroid Build Coastguard Worker // Defines custom mutator, crossover and test functions using text 30*fd525a9cSAndroid Build Coastguard Worker // serialization. This format is more convenient to read. 31*fd525a9cSAndroid Build Coastguard Worker #define DEFINE_TEXT_PROTO_FUZZER(arg) DEFINE_PROTO_FUZZER_IMPL(false, arg) 32*fd525a9cSAndroid Build Coastguard Worker // Defines custom mutator, crossover and test functions using binary 33*fd525a9cSAndroid Build Coastguard Worker // serialization. This makes mutations faster. However often test function is 34*fd525a9cSAndroid Build Coastguard Worker // significantly slower than mutator, so fuzzing rate may stay unchanged. 35*fd525a9cSAndroid Build Coastguard Worker #define DEFINE_BINARY_PROTO_FUZZER(arg) DEFINE_PROTO_FUZZER_IMPL(true, arg) 36*fd525a9cSAndroid Build Coastguard Worker 37*fd525a9cSAndroid Build Coastguard Worker // Registers the callback as a potential mutation performed on the parent 38*fd525a9cSAndroid Build Coastguard Worker // message of a field. This must be called inside an initialization code block. 39*fd525a9cSAndroid Build Coastguard Worker // libFuzzer suggests putting one-time-initialization in a function used to 40*fd525a9cSAndroid Build Coastguard Worker // initialize a static variable inside the fuzzer target. For example: 41*fd525a9cSAndroid Build Coastguard Worker // 42*fd525a9cSAndroid Build Coastguard Worker // static bool Modify( 43*fd525a9cSAndroid Build Coastguard Worker // SomeMessage* message /* Fix or additionally modify the message */, 44*fd525a9cSAndroid Build Coastguard Worker // unsigned int seed /* If random generator is needed use this seed */) { 45*fd525a9cSAndroid Build Coastguard Worker // ... 46*fd525a9cSAndroid Build Coastguard Worker // } 47*fd525a9cSAndroid Build Coastguard Worker // 48*fd525a9cSAndroid Build Coastguard Worker // DEFINE_PROTO_FUZZER(const SomeMessage& msg) { 49*fd525a9cSAndroid Build Coastguard Worker // static PostProcessorRegistration reg(&Modify); 50*fd525a9cSAndroid Build Coastguard Worker // } 51*fd525a9cSAndroid Build Coastguard Worker 52*fd525a9cSAndroid Build Coastguard Worker // Implementation of macros above. 53*fd525a9cSAndroid Build Coastguard Worker #define DEFINE_CUSTOM_PROTO_MUTATOR_IMPL(use_binary, Proto) \ 54*fd525a9cSAndroid Build Coastguard Worker extern "C" size_t LLVMFuzzerCustomMutator( \ 55*fd525a9cSAndroid Build Coastguard Worker uint8_t* data, size_t size, size_t max_size, unsigned int seed) { \ 56*fd525a9cSAndroid Build Coastguard Worker using protobuf_mutator::libfuzzer::CustomProtoMutator; \ 57*fd525a9cSAndroid Build Coastguard Worker Proto input; \ 58*fd525a9cSAndroid Build Coastguard Worker return CustomProtoMutator(use_binary, data, size, max_size, seed, &input); \ 59*fd525a9cSAndroid Build Coastguard Worker } 60*fd525a9cSAndroid Build Coastguard Worker 61*fd525a9cSAndroid Build Coastguard Worker #define DEFINE_CUSTOM_PROTO_CROSSOVER_IMPL(use_binary, Proto) \ 62*fd525a9cSAndroid Build Coastguard Worker extern "C" size_t LLVMFuzzerCustomCrossOver( \ 63*fd525a9cSAndroid Build Coastguard Worker const uint8_t* data1, size_t size1, const uint8_t* data2, size_t size2, \ 64*fd525a9cSAndroid Build Coastguard Worker uint8_t* out, size_t max_out_size, unsigned int seed) { \ 65*fd525a9cSAndroid Build Coastguard Worker using protobuf_mutator::libfuzzer::CustomProtoCrossOver; \ 66*fd525a9cSAndroid Build Coastguard Worker Proto input1; \ 67*fd525a9cSAndroid Build Coastguard Worker Proto input2; \ 68*fd525a9cSAndroid Build Coastguard Worker return CustomProtoCrossOver(use_binary, data1, size1, data2, size2, out, \ 69*fd525a9cSAndroid Build Coastguard Worker max_out_size, seed, &input1, &input2); \ 70*fd525a9cSAndroid Build Coastguard Worker } 71*fd525a9cSAndroid Build Coastguard Worker 72*fd525a9cSAndroid Build Coastguard Worker #define DEFINE_TEST_ONE_PROTO_INPUT_IMPL(use_binary, Proto) \ 73*fd525a9cSAndroid Build Coastguard Worker extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { \ 74*fd525a9cSAndroid Build Coastguard Worker using protobuf_mutator::libfuzzer::LoadProtoInput; \ 75*fd525a9cSAndroid Build Coastguard Worker Proto input; \ 76*fd525a9cSAndroid Build Coastguard Worker if (LoadProtoInput(use_binary, data, size, &input)) \ 77*fd525a9cSAndroid Build Coastguard Worker TestOneProtoInput(input); \ 78*fd525a9cSAndroid Build Coastguard Worker return 0; \ 79*fd525a9cSAndroid Build Coastguard Worker } 80*fd525a9cSAndroid Build Coastguard Worker 81*fd525a9cSAndroid Build Coastguard Worker #define DEFINE_POST_PROCESS_PROTO_MUTATION_IMPL(Proto) \ 82*fd525a9cSAndroid Build Coastguard Worker using PostProcessorRegistration = \ 83*fd525a9cSAndroid Build Coastguard Worker protobuf_mutator::libfuzzer::PostProcessorRegistration<Proto>; 84*fd525a9cSAndroid Build Coastguard Worker 85*fd525a9cSAndroid Build Coastguard Worker #define DEFINE_PROTO_FUZZER_IMPL(use_binary, arg) \ 86*fd525a9cSAndroid Build Coastguard Worker static void TestOneProtoInput(arg); \ 87*fd525a9cSAndroid Build Coastguard Worker using FuzzerProtoType = \ 88*fd525a9cSAndroid Build Coastguard Worker protobuf_mutator::libfuzzer::macro_internal::GetFirstParam< \ 89*fd525a9cSAndroid Build Coastguard Worker decltype(&TestOneProtoInput)>::type; \ 90*fd525a9cSAndroid Build Coastguard Worker DEFINE_CUSTOM_PROTO_MUTATOR_IMPL(use_binary, FuzzerProtoType) \ 91*fd525a9cSAndroid Build Coastguard Worker DEFINE_CUSTOM_PROTO_CROSSOVER_IMPL(use_binary, FuzzerProtoType) \ 92*fd525a9cSAndroid Build Coastguard Worker DEFINE_TEST_ONE_PROTO_INPUT_IMPL(use_binary, FuzzerProtoType) \ 93*fd525a9cSAndroid Build Coastguard Worker DEFINE_POST_PROCESS_PROTO_MUTATION_IMPL(FuzzerProtoType) \ 94*fd525a9cSAndroid Build Coastguard Worker static void TestOneProtoInput(arg) 95*fd525a9cSAndroid Build Coastguard Worker 96*fd525a9cSAndroid Build Coastguard Worker namespace protobuf_mutator { 97*fd525a9cSAndroid Build Coastguard Worker namespace libfuzzer { 98*fd525a9cSAndroid Build Coastguard Worker 99*fd525a9cSAndroid Build Coastguard Worker size_t CustomProtoMutator(bool binary, uint8_t* data, size_t size, 100*fd525a9cSAndroid Build Coastguard Worker size_t max_size, unsigned int seed, 101*fd525a9cSAndroid Build Coastguard Worker protobuf::Message* input); 102*fd525a9cSAndroid Build Coastguard Worker size_t CustomProtoCrossOver(bool binary, const uint8_t* data1, size_t size1, 103*fd525a9cSAndroid Build Coastguard Worker const uint8_t* data2, size_t size2, uint8_t* out, 104*fd525a9cSAndroid Build Coastguard Worker size_t max_out_size, unsigned int seed, 105*fd525a9cSAndroid Build Coastguard Worker protobuf::Message* input1, 106*fd525a9cSAndroid Build Coastguard Worker protobuf::Message* input2); 107*fd525a9cSAndroid Build Coastguard Worker bool LoadProtoInput(bool binary, const uint8_t* data, size_t size, 108*fd525a9cSAndroid Build Coastguard Worker protobuf::Message* input); 109*fd525a9cSAndroid Build Coastguard Worker 110*fd525a9cSAndroid Build Coastguard Worker void RegisterPostProcessor( 111*fd525a9cSAndroid Build Coastguard Worker const protobuf::Descriptor* desc, 112*fd525a9cSAndroid Build Coastguard Worker std::function<void(protobuf::Message* message, unsigned int seed)> 113*fd525a9cSAndroid Build Coastguard Worker callback); 114*fd525a9cSAndroid Build Coastguard Worker 115*fd525a9cSAndroid Build Coastguard Worker template <class Proto> 116*fd525a9cSAndroid Build Coastguard Worker struct PostProcessorRegistration { PostProcessorRegistrationPostProcessorRegistration117*fd525a9cSAndroid Build Coastguard Worker PostProcessorRegistration( 118*fd525a9cSAndroid Build Coastguard Worker const std::function<void(Proto* message, unsigned int seed)>& callback) { 119*fd525a9cSAndroid Build Coastguard Worker RegisterPostProcessor( 120*fd525a9cSAndroid Build Coastguard Worker Proto::descriptor(), 121*fd525a9cSAndroid Build Coastguard Worker [callback](protobuf::Message* message, unsigned int seed) { 122*fd525a9cSAndroid Build Coastguard Worker callback(static_cast<Proto*>(message), seed); 123*fd525a9cSAndroid Build Coastguard Worker }); 124*fd525a9cSAndroid Build Coastguard Worker } 125*fd525a9cSAndroid Build Coastguard Worker }; 126*fd525a9cSAndroid Build Coastguard Worker 127*fd525a9cSAndroid Build Coastguard Worker namespace macro_internal { 128*fd525a9cSAndroid Build Coastguard Worker 129*fd525a9cSAndroid Build Coastguard Worker template <typename T> 130*fd525a9cSAndroid Build Coastguard Worker struct GetFirstParam; 131*fd525a9cSAndroid Build Coastguard Worker 132*fd525a9cSAndroid Build Coastguard Worker template <class Arg> 133*fd525a9cSAndroid Build Coastguard Worker struct GetFirstParam<void (*)(Arg)> { 134*fd525a9cSAndroid Build Coastguard Worker using type = typename std::remove_const< 135*fd525a9cSAndroid Build Coastguard Worker typename std::remove_reference<Arg>::type>::type; 136*fd525a9cSAndroid Build Coastguard Worker }; 137*fd525a9cSAndroid Build Coastguard Worker 138*fd525a9cSAndroid Build Coastguard Worker } // namespace macro_internal 139*fd525a9cSAndroid Build Coastguard Worker 140*fd525a9cSAndroid Build Coastguard Worker } // namespace libfuzzer 141*fd525a9cSAndroid Build Coastguard Worker } // namespace protobuf_mutator 142*fd525a9cSAndroid Build Coastguard Worker 143*fd525a9cSAndroid Build Coastguard Worker #endif // SRC_LIBFUZZER_LIBFUZZER_MACRO_H_ 144