xref: /aosp_15_r20/external/libprotobuf-mutator/src/libfuzzer/libfuzzer_macro.h (revision fd525a9c096e28cf6f8d8719388df0568a611e7b)
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