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