Path: blob/main/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerMutate.h
35262 views
//===- FuzzerMutate.h - Internal header for the Fuzzer ----------*- C++ -* ===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7// fuzzer::MutationDispatcher8//===----------------------------------------------------------------------===//910#ifndef LLVM_FUZZER_MUTATE_H11#define LLVM_FUZZER_MUTATE_H1213#include "FuzzerDefs.h"14#include "FuzzerDictionary.h"15#include "FuzzerOptions.h"16#include "FuzzerRandom.h"1718namespace fuzzer {1920class MutationDispatcher {21public:22MutationDispatcher(Random &Rand, const FuzzingOptions &Options);23~MutationDispatcher() {}24/// Indicate that we are about to start a new sequence of mutations.25void StartMutationSequence();26/// Print the current sequence of mutations. Only prints the full sequence27/// when Verbose is true.28void PrintMutationSequence(bool Verbose = true);29/// Return the current sequence of mutations.30std::string MutationSequence();31/// Indicate that the current sequence of mutations was successful.32void RecordSuccessfulMutationSequence();33/// Mutates data by invoking user-provided mutator.34size_t Mutate_Custom(uint8_t *Data, size_t Size, size_t MaxSize);35/// Mutates data by invoking user-provided crossover.36size_t Mutate_CustomCrossOver(uint8_t *Data, size_t Size, size_t MaxSize);37/// Mutates data by shuffling bytes.38size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);39/// Mutates data by erasing bytes.40size_t Mutate_EraseBytes(uint8_t *Data, size_t Size, size_t MaxSize);41/// Mutates data by inserting a byte.42size_t Mutate_InsertByte(uint8_t *Data, size_t Size, size_t MaxSize);43/// Mutates data by inserting several repeated bytes.44size_t Mutate_InsertRepeatedBytes(uint8_t *Data, size_t Size, size_t MaxSize);45/// Mutates data by changing one byte.46size_t Mutate_ChangeByte(uint8_t *Data, size_t Size, size_t MaxSize);47/// Mutates data by changing one bit.48size_t Mutate_ChangeBit(uint8_t *Data, size_t Size, size_t MaxSize);49/// Mutates data by copying/inserting a part of data into a different place.50size_t Mutate_CopyPart(uint8_t *Data, size_t Size, size_t MaxSize);5152/// Mutates data by adding a word from the manual dictionary.53size_t Mutate_AddWordFromManualDictionary(uint8_t *Data, size_t Size,54size_t MaxSize);5556/// Mutates data by adding a word from the TORC.57size_t Mutate_AddWordFromTORC(uint8_t *Data, size_t Size, size_t MaxSize);5859/// Mutates data by adding a word from the persistent automatic dictionary.60size_t Mutate_AddWordFromPersistentAutoDictionary(uint8_t *Data, size_t Size,61size_t MaxSize);6263/// Tries to find an ASCII integer in Data, changes it to another ASCII int.64size_t Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size, size_t MaxSize);65/// Change a 1-, 2-, 4-, or 8-byte integer in interesting ways.66size_t Mutate_ChangeBinaryInteger(uint8_t *Data, size_t Size, size_t MaxSize);6768/// CrossOver Data with CrossOverWith.69size_t Mutate_CrossOver(uint8_t *Data, size_t Size, size_t MaxSize);7071/// Applies one of the configured mutations.72/// Returns the new size of data which could be up to MaxSize.73size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize);7475/// Applies one of the configured mutations to the bytes of Data76/// that have '1' in Mask.77/// Mask.size() should be >= Size.78size_t MutateWithMask(uint8_t *Data, size_t Size, size_t MaxSize,79const std::vector<uint8_t> &Mask);8081/// Applies one of the default mutations. Provided as a service82/// to mutation authors.83size_t DefaultMutate(uint8_t *Data, size_t Size, size_t MaxSize);8485/// Creates a cross-over of two pieces of Data, returns its size.86size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2,87size_t Size2, uint8_t *Out, size_t MaxOutSize);8889void AddWordToManualDictionary(const Word &W);9091void PrintRecommendedDictionary();9293void SetCrossOverWith(const Unit *U) { CrossOverWith = U; }9495Random &GetRand() { return Rand; }9697private:98struct Mutator {99size_t (MutationDispatcher::*Fn)(uint8_t *Data, size_t Size, size_t Max);100const char *Name;101};102103size_t AddWordFromDictionary(Dictionary &D, uint8_t *Data, size_t Size,104size_t MaxSize);105size_t MutateImpl(uint8_t *Data, size_t Size, size_t MaxSize,106std::vector<Mutator> &Mutators);107108size_t InsertPartOf(const uint8_t *From, size_t FromSize, uint8_t *To,109size_t ToSize, size_t MaxToSize);110size_t CopyPartOf(const uint8_t *From, size_t FromSize, uint8_t *To,111size_t ToSize);112size_t ApplyDictionaryEntry(uint8_t *Data, size_t Size, size_t MaxSize,113DictionaryEntry &DE);114115template <class T>116DictionaryEntry MakeDictionaryEntryFromCMP(T Arg1, T Arg2,117const uint8_t *Data, size_t Size);118DictionaryEntry MakeDictionaryEntryFromCMP(const Word &Arg1, const Word &Arg2,119const uint8_t *Data, size_t Size);120DictionaryEntry MakeDictionaryEntryFromCMP(const void *Arg1, const void *Arg2,121const void *Arg1Mutation,122const void *Arg2Mutation,123size_t ArgSize,124const uint8_t *Data, size_t Size);125126Random &Rand;127const FuzzingOptions Options;128129// Dictionary provided by the user via -dict=DICT_FILE.130Dictionary ManualDictionary;131// Persistent dictionary modified by the fuzzer, consists of132// entries that led to successful discoveries in the past mutations.133Dictionary PersistentAutoDictionary;134135std::vector<DictionaryEntry *> CurrentDictionaryEntrySequence;136137static const size_t kCmpDictionaryEntriesDequeSize = 16;138DictionaryEntry CmpDictionaryEntriesDeque[kCmpDictionaryEntriesDequeSize];139size_t CmpDictionaryEntriesDequeIdx = 0;140141const Unit *CrossOverWith = nullptr;142std::vector<uint8_t> MutateInPlaceHere;143std::vector<uint8_t> MutateWithMaskTemp;144// CustomCrossOver needs its own buffer as a custom implementation may call145// LLVMFuzzerMutate, which in turn may resize MutateInPlaceHere.146std::vector<uint8_t> CustomCrossOverInPlaceHere;147148std::vector<Mutator> Mutators;149std::vector<Mutator> DefaultMutators;150std::vector<Mutator> CurrentMutatorSequence;151};152153} // namespace fuzzer154155#endif // LLVM_FUZZER_MUTATE_H156157158