aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Fuzzer/FuzzerMutate.cpp
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2016-08-17 18:10:42 +0000
committerKostya Serebryany <kcc@google.com>2016-08-17 18:10:42 +0000
commita7398ba024fa834dd733775c9ab1a31f9836010a (patch)
tree559e4e132604780fec5585d22e0f91440b8fcd22 /llvm/lib/Fuzzer/FuzzerMutate.cpp
parent473da657c7206c3e23bcd7374c0de9d9a51ee9f5 (diff)
downloadllvm-a7398ba024fa834dd733775c9ab1a31f9836010a.zip
llvm-a7398ba024fa834dd733775c9ab1a31f9836010a.tar.gz
llvm-a7398ba024fa834dd733775c9ab1a31f9836010a.tar.bz2
[libFuzzer] more mutations
llvm-svn: 278950
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerMutate.cpp')
-rw-r--r--llvm/lib/Fuzzer/FuzzerMutate.cpp87
1 files changed, 69 insertions, 18 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerMutate.cpp b/llvm/lib/Fuzzer/FuzzerMutate.cpp
index 05ea39d..d3eaac0 100644
--- a/llvm/lib/Fuzzer/FuzzerMutate.cpp
+++ b/llvm/lib/Fuzzer/FuzzerMutate.cpp
@@ -32,6 +32,7 @@ MutationDispatcher::MutationDispatcher(Random &Rand,
{&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"},
{&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
{&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"},
+ {&MutationDispatcher::Mutate_CopyPart, "CopyPart"},
{&MutationDispatcher::Mutate_CrossOver, "CrossOver"},
{&MutationDispatcher::Mutate_AddWordFromManualDictionary,
"AddFromManualDict"},
@@ -51,21 +52,9 @@ MutationDispatcher::MutationDispatcher(Random &Rand,
{&MutationDispatcher::Mutate_CustomCrossOver, "CustomCrossOver"});
}
-static char FlipRandomBit(char X, Random &Rand) {
- int Bit = Rand(8);
- char Mask = 1 << Bit;
- char R;
- if (X & (1 << Bit))
- R = X & ~Mask;
- else
- R = X | Mask;
- assert(R != X);
- return R;
-}
-
static char RandCh(Random &Rand) {
if (Rand.RandBool()) return Rand(256);
- const char *Special = "!*'();:@&=+$,/?%#[]123ABCxyz-`~.";
+ const char *Special = "!*'();:@&=+$,/?%#[]012Az-`~.\xff\x00";
return Special[Rand(sizeof(Special) - 1)];
}
@@ -155,7 +144,7 @@ size_t MutationDispatcher::Mutate_ChangeByte(uint8_t *Data, size_t Size,
size_t MutationDispatcher::Mutate_ChangeBit(uint8_t *Data, size_t Size,
size_t MaxSize) {
size_t Idx = Rand(Size);
- Data[Idx] = FlipRandomBit(Data[Idx], Rand);
+ Data[Idx] ^= 1 << Rand(8);
return Size;
}
@@ -198,6 +187,55 @@ size_t MutationDispatcher::AddWordFromDictionary(Dictionary &D, uint8_t *Data,
return Size;
}
+// Overwrites part of To[0,ToSize) with a part of From[0,FromSize).
+// Returns ToSize.
+size_t MutationDispatcher::CopyPartOf(const uint8_t *From, size_t FromSize,
+ uint8_t *To, size_t ToSize) {
+ // Copy From[FromBeg, FromBeg + CopySize) into To[ToBeg, ToBeg + CopySize).
+ size_t ToBeg = Rand(ToSize);
+ size_t CopySize = Rand(ToSize - ToBeg) + 1;
+ assert(ToBeg + CopySize <= ToSize);
+ CopySize = std::min(CopySize, FromSize);
+ size_t FromBeg = Rand(FromSize - CopySize + 1);
+ assert(FromBeg + CopySize <= FromSize);
+ memmove(To + ToBeg, From + FromBeg, CopySize);
+ return ToSize;
+}
+
+// Inserts part of From[0,ToSize) into To.
+// Returns new size of To on success or 0 on failure.
+size_t MutationDispatcher::InsertPartOf(const uint8_t *From, size_t FromSize,
+ uint8_t *To, size_t ToSize,
+ size_t MaxToSize) {
+ if (ToSize >= MaxToSize) return 0;
+ size_t AvailableSpace = MaxToSize - ToSize;
+ size_t MaxCopySize = std::min(AvailableSpace, FromSize);
+ size_t CopySize = Rand(MaxCopySize) + 1;
+ size_t FromBeg = Rand(FromSize - CopySize + 1);
+ assert(FromBeg + CopySize <= FromSize);
+ size_t ToInsertPos = Rand(ToSize + 1);
+ assert(ToInsertPos + CopySize <= MaxToSize);
+ size_t TailSize = ToSize - ToInsertPos;
+ if (To == From) {
+ MutateInPlaceHere.resize(MaxToSize);
+ memcpy(MutateInPlaceHere.data(), From + FromBeg, CopySize);
+ memmove(To + ToInsertPos + CopySize, To + ToInsertPos, TailSize);
+ memmove(To + ToInsertPos, MutateInPlaceHere.data(), CopySize);
+ } else {
+ memmove(To + ToInsertPos + CopySize, To + ToInsertPos, TailSize);
+ memmove(To + ToInsertPos, From + FromBeg, CopySize);
+ }
+ return ToSize + CopySize;
+}
+
+size_t MutationDispatcher::Mutate_CopyPart(uint8_t *Data, size_t Size,
+ size_t MaxSize) {
+ if (Rand.RandBool())
+ return CopyPartOf(Data, Size, Data, Size);
+ else
+ return InsertPartOf(Data, Size, Data, Size, MaxSize);
+}
+
size_t MutationDispatcher::Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size,
size_t MaxSize) {
size_t B = Rand(Size);
@@ -235,12 +273,25 @@ size_t MutationDispatcher::Mutate_CrossOver(uint8_t *Data, size_t Size,
size_t MaxSize) {
if (!Corpus || Corpus->size() < 2 || Size == 0) return 0;
size_t Idx = Rand(Corpus->size());
- const Unit &Other = (*Corpus)[Idx];
- if (Other.empty()) return 0;
+ const Unit &O = (*Corpus)[Idx];
+ if (O.empty()) return 0;
MutateInPlaceHere.resize(MaxSize);
auto &U = MutateInPlaceHere;
- size_t NewSize =
- CrossOver(Data, Size, Other.data(), Other.size(), U.data(), U.size());
+ size_t NewSize;
+ switch(Rand(3)) {
+ case 0:
+ NewSize = CrossOver(Data, Size, O.data(), O.size(), U.data(), U.size());
+ break;
+ case 1:
+ NewSize = InsertPartOf(O.data(), O.size(), U.data(), U.size(), MaxSize);
+ if (NewSize)
+ break;
+ // Fallthrough
+ case 2:
+ NewSize = CopyPartOf(O.data(), O.size(), U.data(), U.size());
+ break;
+ default: assert(0);
+ }
assert(NewSize > 0 && "CrossOver returned empty unit");
assert(NewSize <= MaxSize && "CrossOver returned overisized unit");
memcpy(Data, U.data(), NewSize);