1 /* 2 * Copyright 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef __VTS_PROTO_FUZZER_MUTATOR_H_ 18 #define __VTS_PROTO_FUZZER_MUTATOR_H_ 19 20 #include <functional> 21 #include <memory> 22 #include <string> 23 #include <unordered_map> 24 25 #include "ProtoFuzzerRunner.h" 26 #include "ProtoFuzzerUtils.h" 27 28 namespace android { 29 namespace vts { 30 namespace fuzzer { 31 32 using BiasedRandomScalarGen = std::function<uint64_t(Random &rand)>; 33 using Odds = std::pair<uint64_t, uint64_t>; 34 using VarMutateFn = std::function<VarInstance(const VarInstance &)>; 35 using VarRandomGenFn = std::function<VarInstance(const VarSpec &)>; 36 using VarTransformFn = std::function<VariableSpecificationMessage( 37 const VariableSpecificationMessage &)>; 38 39 // Encapsulates heuristic strategy for biased mutation/random generation. 40 struct ProtoFuzzerMutatorConfig { 41 // Generates biased random scalars. 42 BiasedRandomScalarGen scalar_bias_ = [](Random &rand) { return rand.Rand(); }; 43 // Used to decide if enum will be mutated/generated like a scalar. 44 Odds enum_bias_ = {0, 1}; 45 // Odds that a function in an execution is mutated rather than regenerated. 46 Odds func_mutated_ = {100, 1}; 47 // Default size used to randomly generate a vector. 48 size_t default_vector_size_ = 64; 49 // Default size used to randomly generate a string. 50 size_t default_string_size_ = 16; 51 }; 52 53 // Provides methods for mutation or random generation. 54 class ProtoFuzzerMutator { 55 public: 56 ProtoFuzzerMutator(Random &, std::unordered_map<std::string, TypeSpec>, 57 ProtoFuzzerMutatorConfig); 58 // Generates a random ExecSpec. 59 ExecSpec RandomGen(const IfaceDescTbl &, size_t); 60 // Mutates in-place an ExecSpec. 61 void Mutate(const IfaceDescTbl &, ExecSpec *); 62 // Generates a random FuncSpec. 63 FuncSpec RandomGen(const FuncSpec &); 64 // Mutates a FuncSpec. 65 FuncSpec Mutate(const FuncSpec &); 66 // Generates a random VarInstance. 67 VarInstance RandomGen(const VarSpec &); 68 // Mutates a VarInstance. 69 VarInstance Mutate(const VarInstance &); 70 71 private: 72 // Randomly selects an interface. 73 const CompSpec *RandomSelectIface(const IfaceDescTbl &); 74 75 // Used for mutation/random generation of VarInstance. 76 VarInstance ArrayRandomGen(const VarSpec &); 77 VarInstance ArrayMutate(const VarInstance &); 78 VarInstance EnumRandomGen(const VarSpec &); 79 VarInstance EnumMutate(const VarInstance &); 80 VarInstance ScalarRandomGen(const VarSpec &); 81 VarInstance ScalarMutate(const VarInstance &); 82 VarInstance StringRandomGen(const VarSpec &); 83 VarInstance StringMutate(const VarInstance &); 84 VarInstance StructRandomGen(const VarSpec &); 85 VarInstance StructMutate(const VarInstance &); 86 VarInstance UnionRandomGen(const VarSpec &); 87 VarInstance UnionMutate(const VarInstance &); 88 VarInstance VectorRandomGen(const VarSpec &); 89 VarInstance VectorMutate(const VarInstance &); 90 91 // Used for mutation/random generation of ScalarData. 92 ScalarData RandomGen(const ScalarData &, const std::string &); 93 ScalarData Mutate(const ScalarData &, const string &); 94 // Used for mutation/random generation of variables of fundamental data types 95 // e.g. char, int, double. 96 template <typename T> 97 T RandomGen(T); 98 template <typename T> 99 T Mutate(T); 100 bool RandomGen(bool); 101 bool Mutate(bool); 102 float Mutate(float); 103 double Mutate(double); 104 // Generates a random ASCII character. 105 char RandomAsciiChar(); 106 107 // Looks up predefined type by name. 108 const TypeSpec &FindPredefinedType(std::string); 109 110 // 64-bit random number generator. 111 Random &rand_; 112 // Used to look up definition of a predefined type by its name. 113 std::unordered_map<std::string, TypeSpec> predefined_types_; 114 // Used to delegate mutation/random generation of VariableSpecifationMessage 115 // of different VariableType to mutation/random delegation function for that 116 // VariableType. 117 std::unordered_map<VariableType, VarMutateFn> mutate_fns_; 118 std::unordered_map<VariableType, VarRandomGenFn> random_gen_fns_; 119 // Used for biased mutation/random generation of variables. 120 ProtoFuzzerMutatorConfig mutator_config_; 121 }; 122 123 } // namespace fuzzer 124 } // namespace vts 125 } // namespace android 126 127 #endif // __VTS_PROTO_FUZZER_MUTATOR__ 128