Home | History | Annotate | Download | only in include
      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