Skip to content

Commit

Permalink
ClusterFuzz-compatible stack traces on abort
Browse files Browse the repository at this point in the history
  • Loading branch information
guidovranken committed May 22, 2019
1 parent f210f86 commit a447fa0
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 4 deletions.
38 changes: 34 additions & 4 deletions executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "tests.h"
#include <cryptofuzz/util.h>
#include <fuzzing/memory.hpp>
#include <algorithm>

extern "C" {
//__attribute__((section("__libfuzzer_extra_counters")))
Expand Down Expand Up @@ -139,7 +140,12 @@ template<> void ExecutorBase<component::Ciphertext, operation::SymmetricEncrypt>
printf("Operation:\n%s\n", op.ToString().c_str());
printf("Ciphertext: %s\n", util::HexDump(result.second->ciphertext.Get()).c_str());
printf("Tag: %s\n", result.second->tag ? util::HexDump(result.second->tag->Get()).c_str() : "nullopt");
abort();
abort(
{module->name},
op.Name(),
op.GetAlgorithmString(),
"cannot decrypt ciphertext"
);
} else if ( cleartext->Get() != op.cleartext.Get() ) {
/* Decryption ostensibly succeeded, but the cleartext returned by OpSymmetricDecrypt()
* does not match to original cleartext */
Expand All @@ -149,7 +155,12 @@ template<> void ExecutorBase<component::Ciphertext, operation::SymmetricEncrypt>
printf("Ciphertext: %s\n", util::HexDump(result.second->ciphertext.Get()).c_str());
printf("Tag: %s\n", result.second->tag ? util::HexDump(result.second->tag->Get()).c_str() : "nullopt");
printf("Purported cleartext: %s\n", util::HexDump(cleartext->Get()).c_str());
abort();
abort(
{module->name},
op.Name(),
op.GetAlgorithmString(),
"cannot decrypt ciphertext"
);
}
}
}
Expand Down Expand Up @@ -377,11 +388,30 @@ void ExecutorBase<ResultType, OperationType>::compare(const ResultSet& results,
printf("Module %s result:\n\n%s\n\n", filtered[i-1].first->name.c_str(), util::ToString(*prev).c_str());
printf("Module %s result:\n\n%s\n\n", filtered[i].first->name.c_str(), util::ToString(*cur).c_str());

abort();
abort(
{filtered[i-1].first->name.c_str(), filtered[i].first->name.c_str()},
op.Name(),
op.GetAlgorithmString(),
"difference"
);
}
}
}

template <class ResultType, class OperationType>
void ExecutorBase<ResultType, OperationType>::abort(std::vector<std::string> moduleNames, const std::string operation, const std::string algorithm, const std::string reason) const {
std::sort(moduleNames.begin(), moduleNames.end());

printf("Assertion failure: ");
for (const auto& moduleName : moduleNames) {
printf("%s-", moduleName.c_str());
}
printf("%s-%s-%s\n", operation.c_str(), algorithm.c_str(), reason.c_str());
fflush(stdout);

::abort();
}

template <class ResultType, class OperationType>
OperationType ExecutorBase<ResultType, OperationType>::getOp(Datasource* parentDs, const uint8_t* data, const size_t size) const {
Datasource ds(data, size);
Expand Down Expand Up @@ -441,7 +471,7 @@ void ExecutorBase<ResultType, OperationType>::Run(Datasource& parentDs, const ui


/* Enable this to run every operation on every loaded module */
#if 0
#if 1
{
std::vector< std::pair<std::shared_ptr<Module>, OperationType> > newOperations;

Expand Down
1 change: 1 addition & 0 deletions executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class ExecutorBase {
void postprocess(std::shared_ptr<Module> module, OperationType& op, const ResultPair& result) const;
std::optional<ResultType> callModule(std::shared_ptr<Module> module, OperationType& op) const;

void abort(std::vector<std::string> moduleNames, const std::string operation, const std::string algorithm, const std::string reason) const;
public:
void Run(Datasource& parentDs, const uint8_t* data, const size_t size) const;
ExecutorBase(const uint64_t operationID, const std::map<uint64_t, std::shared_ptr<Module> >& modules);
Expand Down
28 changes: 28 additions & 0 deletions include/cryptofuzz/operations.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <cryptofuzz/components.h>
#include <cryptofuzz/repository.h>
#include <fuzzing/datasource/datasource.hpp>

namespace cryptofuzz {
Expand All @@ -16,7 +17,11 @@ class Operation {
modifier(std::move(modifier))
{ }

virtual std::string Name(void) const = 0;
virtual std::string ToString(void) const = 0;
virtual std::string GetAlgorithmString(void) const {
return "(no algorithm)";
}
};

class Digest : public Operation {
Expand All @@ -30,7 +35,11 @@ class Digest : public Operation {
digestType(ds)
{ }

std::string Name(void) const override;
std::string ToString(void) const override;
std::string GetAlgorithmString(void) const override {
return repository::DigestToString(digestType.Get());
}
};

class HMAC : public Operation {
Expand All @@ -46,7 +55,11 @@ class HMAC : public Operation {
cipher(ds)
{ }

std::string Name(void) const override;
std::string ToString(void) const override;
std::string GetAlgorithmString(void) const override {
return repository::DigestToString(digestType.Get());
}
};

class SymmetricEncrypt : public Operation {
Expand All @@ -69,7 +82,11 @@ class SymmetricEncrypt : public Operation {
std::make_optional<uint64_t>(ds.Get<uint64_t>() % (10*1024*1024)) )
{ }

std::string Name(void) const override;
std::string ToString(void) const override;
std::string GetAlgorithmString(void) const override {
return repository::CipherToString(cipher.cipherType.Get());
}
};

class SymmetricDecrypt : public Operation {
Expand All @@ -91,7 +108,11 @@ class SymmetricDecrypt : public Operation {
{ }
SymmetricDecrypt(const SymmetricEncrypt& opSymmetricEncrypt, const component::Ciphertext ciphertext, const uint64_t cleartextSize, std::optional<component::AAD> aad, component::Modifier modifier);

std::string Name(void) const override;
std::string ToString(void) const override;
std::string GetAlgorithmString(void) const override {
return repository::CipherToString(cipher.cipherType.Get());
}
};

class KDF_SCRYPT : public Operation {
Expand All @@ -114,6 +135,7 @@ class KDF_SCRYPT : public Operation {
keySize(ds.Get<uint64_t>() % 1024)
{ }

std::string Name(void) const override;
std::string ToString(void) const override;
};

Expand All @@ -135,6 +157,7 @@ class KDF_HKDF : public Operation {
keySize(ds.Get<uint64_t>() % 1024)
{ }

std::string Name(void) const override;
std::string ToString(void) const override;
};

Expand All @@ -154,6 +177,7 @@ class KDF_TLS1_PRF : public Operation {
keySize(ds.Get<uint64_t>() % 1024)
{ }

std::string Name(void) const override;
std::string ToString(void) const override;
};

Expand All @@ -175,6 +199,7 @@ class KDF_PBKDF2 : public Operation {
keySize(ds.Get<uint64_t>() % 1024)
{ }

std::string Name(void) const override;
std::string ToString(void) const override;
};

Expand All @@ -189,6 +214,7 @@ class CMAC : public Operation {
cipher(ds)
{ }

std::string Name(void) const override;
std::string ToString(void) const override;
};

Expand All @@ -208,6 +234,7 @@ class Sign : public Operation {
signatureSize(ds.Get<uint64_t>() % (10*1024*1024))
{ }

std::string Name(void) const override;
std::string ToString(void) const override;
};

Expand All @@ -227,6 +254,7 @@ class Verify : public Operation {
{ }
Verify(const Sign& opSign, const component::Signature signature, component::Modifier modifier);

std::string Name(void) const override;
std::string ToString(void) const override;
};

Expand Down
11 changes: 11 additions & 0 deletions operation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
namespace cryptofuzz {
namespace operation {

std::string Digest::Name(void) const { return "Digest"; }
std::string Digest::ToString(void) const {
std::stringstream ss;

Expand All @@ -16,6 +17,7 @@ std::string Digest::ToString(void) const {
return ss.str();
}

std::string HMAC::Name(void) const { return "HMAC"; }
std::string HMAC::ToString(void) const {
std::stringstream ss;

Expand All @@ -26,6 +28,7 @@ std::string HMAC::ToString(void) const {
return ss.str();
}

std::string SymmetricEncrypt::Name(void) const { return "SymmetricEncrypt"; }
std::string SymmetricEncrypt::ToString(void) const {
std::stringstream ss;

Expand All @@ -41,6 +44,7 @@ std::string SymmetricEncrypt::ToString(void) const {
return ss.str();
}

std::string SymmetricDecrypt::Name(void) const { return "SymmetricDecrypt"; }
std::string SymmetricDecrypt::ToString(void) const {
std::stringstream ss;

Expand All @@ -66,6 +70,7 @@ SymmetricDecrypt::SymmetricDecrypt(const SymmetricEncrypt& opSymmetricEncrypt, c
cleartextSize(cleartextSize)
{ }

std::string KDF_SCRYPT::Name(void) const { return "KDF_SCRYPT"; }
std::string KDF_SCRYPT::ToString(void) const {
std::stringstream ss;

Expand All @@ -79,6 +84,7 @@ std::string KDF_SCRYPT::ToString(void) const {
return ss.str();
}

std::string KDF_HKDF::Name(void) const { return "KDF_HKDF"; }
std::string KDF_HKDF::ToString(void) const {
std::stringstream ss;

Expand All @@ -91,6 +97,7 @@ std::string KDF_HKDF::ToString(void) const {
return ss.str();
}

std::string KDF_TLS1_PRF::Name(void) const { return "KDF_TLS1_PRF"; }
std::string KDF_TLS1_PRF::ToString(void) const {
std::stringstream ss;

Expand All @@ -102,6 +109,7 @@ std::string KDF_TLS1_PRF::ToString(void) const {
return ss.str();
}

std::string KDF_PBKDF2::Name(void) const { return "KDF_PBKDF2"; }
std::string KDF_PBKDF2::ToString(void) const {
std::stringstream ss;

Expand All @@ -114,6 +122,7 @@ std::string KDF_PBKDF2::ToString(void) const {
return ss.str();
}

std::string CMAC::Name(void) const { return "CMAC"; }
std::string CMAC::ToString(void) const {
std::stringstream ss;

Expand All @@ -127,6 +136,7 @@ std::string CMAC::ToString(void) const {
return ss.str();
}

std::string Sign::Name(void) const { return "Sign"; }
std::string Sign::ToString(void) const {
std::stringstream ss;

Expand All @@ -137,6 +147,7 @@ std::string Sign::ToString(void) const {
return ss.str();
}

std::string Verify::Name(void) const { return "Verify"; }
std::string Verify::ToString(void) const {
std::stringstream ss;

Expand Down

0 comments on commit a447fa0

Please sign in to comment.