1*fd525a9cSAndroid Build Coastguard Worker // Copyright 2016 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_MUTATOR_H_ 16*fd525a9cSAndroid Build Coastguard Worker #define SRC_MUTATOR_H_ 17*fd525a9cSAndroid Build Coastguard Worker 18*fd525a9cSAndroid Build Coastguard Worker #include <stddef.h> 19*fd525a9cSAndroid Build Coastguard Worker #include <stdint.h> 20*fd525a9cSAndroid Build Coastguard Worker 21*fd525a9cSAndroid Build Coastguard Worker #include <functional> 22*fd525a9cSAndroid Build Coastguard Worker #include <memory> 23*fd525a9cSAndroid Build Coastguard Worker #include <random> 24*fd525a9cSAndroid Build Coastguard Worker #include <string> 25*fd525a9cSAndroid Build Coastguard Worker #include <unordered_map> 26*fd525a9cSAndroid Build Coastguard Worker #include <vector> 27*fd525a9cSAndroid Build Coastguard Worker 28*fd525a9cSAndroid Build Coastguard Worker #include "port/protobuf.h" 29*fd525a9cSAndroid Build Coastguard Worker #include "src/random.h" 30*fd525a9cSAndroid Build Coastguard Worker 31*fd525a9cSAndroid Build Coastguard Worker namespace protobuf_mutator { 32*fd525a9cSAndroid Build Coastguard Worker 33*fd525a9cSAndroid Build Coastguard Worker // Randomly makes incremental change in the given protobuf. 34*fd525a9cSAndroid Build Coastguard Worker // Usage example: 35*fd525a9cSAndroid Build Coastguard Worker // protobuf_mutator::Mutator mutator(1); 36*fd525a9cSAndroid Build Coastguard Worker // MyMessage message; 37*fd525a9cSAndroid Build Coastguard Worker // message.ParseFromString(encoded_message); 38*fd525a9cSAndroid Build Coastguard Worker // mutator.Mutate(&message, 10000); 39*fd525a9cSAndroid Build Coastguard Worker // 40*fd525a9cSAndroid Build Coastguard Worker // Class implements very basic mutations of fields. E.g. it just flips bits for 41*fd525a9cSAndroid Build Coastguard Worker // integers, floats and strings. Also it increases, decreases size of 42*fd525a9cSAndroid Build Coastguard Worker // strings only by one. For better results users should override 43*fd525a9cSAndroid Build Coastguard Worker // protobuf_mutator::Mutator::Mutate* methods with more useful logic, e.g. using 44*fd525a9cSAndroid Build Coastguard Worker // library like libFuzzer. 45*fd525a9cSAndroid Build Coastguard Worker class Mutator { 46*fd525a9cSAndroid Build Coastguard Worker public: 47*fd525a9cSAndroid Build Coastguard Worker // seed: value to initialize random number generator. 48*fd525a9cSAndroid Build Coastguard Worker Mutator() = default; 49*fd525a9cSAndroid Build Coastguard Worker virtual ~Mutator() = default; 50*fd525a9cSAndroid Build Coastguard Worker 51*fd525a9cSAndroid Build Coastguard Worker // Initialized internal random number generator. 52*fd525a9cSAndroid Build Coastguard Worker void Seed(uint32_t value); 53*fd525a9cSAndroid Build Coastguard Worker 54*fd525a9cSAndroid Build Coastguard Worker // message: message to mutate. 55*fd525a9cSAndroid Build Coastguard Worker // max_size_hint: approximate max ByteSize() of resulting message. Method does 56*fd525a9cSAndroid Build Coastguard Worker // not guarantee that real result will be strictly smaller than value. Caller 57*fd525a9cSAndroid Build Coastguard Worker // could repeat mutation if result was larger than expected. 58*fd525a9cSAndroid Build Coastguard Worker void Mutate(protobuf::Message* message, size_t max_size_hint); 59*fd525a9cSAndroid Build Coastguard Worker 60*fd525a9cSAndroid Build Coastguard Worker void CrossOver(const protobuf::Message& message1, protobuf::Message* message2, 61*fd525a9cSAndroid Build Coastguard Worker size_t max_size_hint); 62*fd525a9cSAndroid Build Coastguard Worker 63*fd525a9cSAndroid Build Coastguard Worker // Makes message initialized and calls post processors to make it valid. 64*fd525a9cSAndroid Build Coastguard Worker void Fix(protobuf::Message* message); 65*fd525a9cSAndroid Build Coastguard Worker 66*fd525a9cSAndroid Build Coastguard Worker // Callback to postprocess mutations. 67*fd525a9cSAndroid Build Coastguard Worker // Implementation should use seed to initialize random number generators. 68*fd525a9cSAndroid Build Coastguard Worker using PostProcess = 69*fd525a9cSAndroid Build Coastguard Worker std::function<void(protobuf::Message* message, unsigned int seed)>; 70*fd525a9cSAndroid Build Coastguard Worker 71*fd525a9cSAndroid Build Coastguard Worker // Register callback which will be called after every message mutation. 72*fd525a9cSAndroid Build Coastguard Worker // In this callback fuzzer may adjust content of the message or mutate some 73*fd525a9cSAndroid Build Coastguard Worker // fields in some fuzzer specific way. 74*fd525a9cSAndroid Build Coastguard Worker void RegisterPostProcessor(const protobuf::Descriptor* desc, 75*fd525a9cSAndroid Build Coastguard Worker PostProcess callback); 76*fd525a9cSAndroid Build Coastguard Worker 77*fd525a9cSAndroid Build Coastguard Worker protected: 78*fd525a9cSAndroid Build Coastguard Worker // TODO(vitalybuka): Consider to replace with single mutate (uint8_t*, size). 79*fd525a9cSAndroid Build Coastguard Worker virtual int32_t MutateInt32(int32_t value); 80*fd525a9cSAndroid Build Coastguard Worker virtual int64_t MutateInt64(int64_t value); 81*fd525a9cSAndroid Build Coastguard Worker virtual uint32_t MutateUInt32(uint32_t value); 82*fd525a9cSAndroid Build Coastguard Worker virtual uint64_t MutateUInt64(uint64_t value); 83*fd525a9cSAndroid Build Coastguard Worker virtual float MutateFloat(float value); 84*fd525a9cSAndroid Build Coastguard Worker virtual double MutateDouble(double value); 85*fd525a9cSAndroid Build Coastguard Worker virtual bool MutateBool(bool value); 86*fd525a9cSAndroid Build Coastguard Worker virtual size_t MutateEnum(size_t index, size_t item_count); 87*fd525a9cSAndroid Build Coastguard Worker virtual std::string MutateString(const std::string& value, 88*fd525a9cSAndroid Build Coastguard Worker int size_increase_hint); 89*fd525a9cSAndroid Build Coastguard Worker random()90*fd525a9cSAndroid Build Coastguard Worker RandomEngine* random() { return &random_; } 91*fd525a9cSAndroid Build Coastguard Worker 92*fd525a9cSAndroid Build Coastguard Worker private: 93*fd525a9cSAndroid Build Coastguard Worker friend class FieldMutator; 94*fd525a9cSAndroid Build Coastguard Worker friend class TestMutator; 95*fd525a9cSAndroid Build Coastguard Worker bool MutateImpl(const std::vector<const protobuf::Message*>& sources, 96*fd525a9cSAndroid Build Coastguard Worker const std::vector<protobuf::Message*>& messages, 97*fd525a9cSAndroid Build Coastguard Worker bool copy_clone_only, int size_increase_hint); 98*fd525a9cSAndroid Build Coastguard Worker std::string MutateUtf8String(const std::string& value, 99*fd525a9cSAndroid Build Coastguard Worker int size_increase_hint); 100*fd525a9cSAndroid Build Coastguard Worker bool IsInitialized(const protobuf::Message& message) const; 101*fd525a9cSAndroid Build Coastguard Worker bool keep_initialized_ = true; 102*fd525a9cSAndroid Build Coastguard Worker size_t random_to_default_ratio_ = 100; 103*fd525a9cSAndroid Build Coastguard Worker RandomEngine random_; 104*fd525a9cSAndroid Build Coastguard Worker using PostProcessors = 105*fd525a9cSAndroid Build Coastguard Worker std::unordered_multimap<const protobuf::Descriptor*, PostProcess>; 106*fd525a9cSAndroid Build Coastguard Worker PostProcessors post_processors_; 107*fd525a9cSAndroid Build Coastguard Worker }; 108*fd525a9cSAndroid Build Coastguard Worker 109*fd525a9cSAndroid Build Coastguard Worker } // namespace protobuf_mutator 110*fd525a9cSAndroid Build Coastguard Worker 111*fd525a9cSAndroid Build Coastguard Worker #endif // SRC_MUTATOR_H_ 112