Skip to content

Commit

Permalink
changed the custom mutator example to do something meaningful
Browse files Browse the repository at this point in the history
  • Loading branch information
PBetzler committed Jul 25, 2024
1 parent 033d871 commit 7476ce5
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 25 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Execute with:
cifuzz run structured_input_checks_fuzz_test
```
* [Custom Mutator Example](src/advanced_examples/custom_mutator_example_checks_test.cpp#L37):
An example that is build on top of the [Structure Aware Inputs Example](src/advanced_examples/explore_me.cpp#L8) and shows how to utilize custom mutators to change how the inputs are mutated.
An example that shows how to utilize custom mutators to make sure the fuzzer only creates valid inputs.
Execute with:
```sh
cifuzz run custom_mutator_example_checks_fuzz_test
Expand Down
1 change: 1 addition & 0 deletions src/advanced_examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ target_include_directories(explore_me_advanced PRIVATE

target_link_libraries(explore_me_advanced
OpenSSL::Crypto
-lz
)

foreach(TestType IN ITEMS
Expand Down
77 changes: 54 additions & 23 deletions src/advanced_examples/custom_mutator_example_checks_test.cpp
Original file line number Diff line number Diff line change
@@ -1,36 +1,46 @@
#include <cifuzz/cifuzz.h>
#include <cstdlib>
#include <fuzzer/FuzzedDataProvider.h>
#include <iostream>
#include <zlib.h>

#include "explore_me.h"

#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
#include <gtest/gtest.h>

TEST(ExploreStructuredInputChecks, DeveloperTest) {
InputStruct inputStruct = (InputStrut) {.a=0, .b= 10, .c="Developer"};
EXPECT_NO_THROW(ExploreStructuredInputChecks(inputStruct));
TEST(ExploreCompressedInputChecks, HI) {
uint8_t uncompressed[3];
size_t uncompressedLen = sizeof(uncompressed);
uncompressed[0] = 'H';
uncompressed[1] = 'I';
uncompressed[2] = '\0';
uint8_t compressed[3];
size_t compressedLen = sizeof(compressed);
if (Z_OK != compress(compressed, &compressedLen, uncompressed, uncompressedLen)) {
abort();
}
EXPECT_NO_THROW(ExploreCompressedInputChecks(compressed, compressedLen));
}

TEST(ExploreStructuredInputChecks, MaintainerTest) {
InputStruct inputStruct = (InputStruct) {.a=20, .b= -10, .c="Maintainer"};
EXPECT_NO_THROW(ExploreStructuredInputChecks(inputStruct));
TEST(ExploreCompressedInputChecks, HO) {
uint8_t uncompressed[3];
size_t uncompressedLen = sizeof(uncompressed);
uncompressed[0] = 'H';
uncompressed[1] = 'O';
uncompressed[2] = '\0';
uint8_t compressed[3];
size_t compressedLen = sizeof(compressed);
if (Z_OK != compress(compressed, &compressedLen, uncompressed, uncompressedLen)) {
abort();
}
EXPECT_NO_THROW(ExploreCompressedInputChecks(compressed, compressedLen));
}

#endif

FUZZ_TEST(const uint8_t *data, size_t size) {
FuzzedDataProvider fdp(data, size);
long a = fdp.ConsumeIntegral<long>();
long b = fdp.ConsumeIntegral<long>();
std::string c = fdp.ConsumeRemainingBytesAsString();

InputStruct inputStruct = (InputStruct) {
.a = a,
.b = b,
.c = c,
};
ExploreStructuredInputChecks(inputStruct);
ExploreCompressedInputChecks(data, size);
}

extern "C" size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);
Expand All @@ -39,15 +49,36 @@ extern "C" size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);
Custom mutator example. In this case we only print out once that we are in a custom mutator and then use te regular one,
but you can also change the Data how you like. Make sure to return the new length.
*/
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
size_t MaxSize, unsigned int Seed) {
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *data, size_t size,
size_t maxSize, unsigned int seed) {

static bool Printed;
if (!Printed) {
static bool printed;
if (!printed) {
std::cerr << "In custom mutator.\n";
Printed = true;
printed = true;
}

uint8_t uncompressed[100];
size_t uncompressedLen = sizeof(uncompressed);
size_t compressedLen = maxSize;
if (Z_OK != uncompress(uncompressed, &uncompressedLen, data, size)) {
// The data didn't uncompress.
// So, it's either a broken input and we want to ignore it,
// or we've started fuzzing from an empty corpus and we need to supply
// out first properly compressed input.
uint8_t dummy[] = {'H', 'i'};
if (Z_OK != compress(data, &compressedLen, dummy, sizeof(dummy))) {
return 0;
} else {
// fprintf(stderr, "Dummy: max %zd res %zd\n", MaxSize, CompressedLen);
return compressedLen;
}
}

uncompressedLen = LLVMFuzzerMutate(uncompressed, uncompressedLen, sizeof(uncompressed));
if (Z_OK != compress(data, &compressedLen, uncompressed, uncompressedLen)) {
return 0;
}
// make sure to return the new Size (that needs to be <= MaxSize) as return value!
return LLVMFuzzerMutate(Data, Size, MaxSize);
return compressedLen;
}
17 changes: 16 additions & 1 deletion src/advanced_examples/explore_me.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <cstring>

#include <zlib.h>
#include "explore_me.h"

static long insecureEncrypt(long input);
Expand All @@ -17,6 +17,21 @@ void ExploreStructuredInputChecks(InputStruct inputStruct){
return;
}

void ExploreCompressedInputChecks(const uint8_t *Data, size_t Size){
uint8_t Uncompressed[100];
size_t UncompressedLen = sizeof(Uncompressed);
// Check if uncompression was successful
if (Z_OK != uncompress(Uncompressed, &UncompressedLen, Data, Size)) {
// Uncompression was not successfull
// Just return and throw input away
return;
}
if (UncompressedLen < 2) return;
if (Uncompressed[0] == 'C' && Uncompressed[1] == 'I') {
trigger_double_free();
}
}

static long insecureEncrypt(long input) {
long key = 0xefe4eb93215cb6b0L;
return input ^ key;
Expand Down
1 change: 1 addition & 0 deletions src/advanced_examples/explore_me.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ struct InputStruct {
};

void ExploreStructuredInputChecks(InputStruct inputStruct);
void ExploreCompressedInputChecks(const uint8_t *Data, size_t Size);

0 comments on commit 7476ce5

Please sign in to comment.