Skip to content
This repository has been archived by the owner on Apr 17, 2019. It is now read-only.

Commit

Permalink
Ordering service fuzzing (#1829)
Browse files Browse the repository at this point in the history
* Add OS fuzzing for SendBatches endpoint
* Add fuzzing for request proposal endpoint

Signed-off-by: luckychess <[email protected]>
Signed-off-by: Konstantin Munichev <[email protected]>
  • Loading branch information
luckychess authored and Igor Egorov committed Nov 12, 2018
1 parent 0a38453 commit f23dcea
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 29 deletions.
22 changes: 19 additions & 3 deletions test/fuzzing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,27 @@ target_link_libraries(find_fuzzing

add_executable(ordering_gate_fuzz ordering_gate_fuzz.cpp)
target_link_libraries(ordering_gate_fuzz
rxcpp
gtest::gtest
gmock::gmock
on_demand_ordering_gate
shared_model_default_builders
shared_model_stateless_validation
protobuf-mutator
)
)

add_executable(send_batches_fuzz send_batches_fuzz.cpp)
target_link_libraries(send_batches_fuzz
gtest::gtest
gmock::gmock
on_demand_ordering_service
on_demand_ordering_service_transport_grpc
protobuf-mutator
)

add_executable(request_proposal_fuzz request_proposal_fuzz.cpp)
target_link_libraries(request_proposal_fuzz
gtest::gtest
gmock::gmock
on_demand_ordering_service
on_demand_ordering_service_transport_grpc
protobuf-mutator
)
54 changes: 28 additions & 26 deletions test/fuzzing/ordering_gate_fuzz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,44 @@
* SPDX-License-Identifier: Apache-2.0
*/

#include <memory>
#include <libfuzzer/libfuzzer_macro.h>
#include "ordering/impl/on_demand_ordering_gate.hpp"
#include <memory>
#include "backend/protobuf/proto_block_factory.hpp"
#include "module/irohad/ordering/ordering_mocks.hpp"
#include "module/shared_model/interface_mocks.hpp"
#include "backend/protobuf/proto_block_factory.hpp"
#include "ordering/impl/on_demand_ordering_gate.hpp"
#include "validators/default_validator.hpp"

using namespace iroha::ordering;
using namespace testing;

struct OrderingGateFixture {
std::shared_ptr<shared_model::proto::ProtoBlockFactory> block_factory_;
std::shared_ptr<MockOnDemandOrderingService> ordering_service_;
std::shared_ptr<transport::MockOdOsNotification> network_client_;
std::shared_ptr<NiceMock<MockOnDemandOrderingService>> ordering_service_;
std::shared_ptr<NiceMock<transport::MockOdOsNotification>> network_client_;

rxcpp::subjects::subject<OnDemandOrderingGate::BlockRoundEventType> rounds_;
MockUnsafeProposalFactory *proposal_factory_;
NiceMock<MockUnsafeProposalFactory> *proposal_factory_;
std::shared_ptr<OnDemandOrderingGate> ordering_gate_;
iroha::consensus::Round initial_round_ = {2, 1};

OrderingGateFixture() :
block_factory_(std::make_shared<shared_model::proto::ProtoBlockFactory>(std::make_unique<
shared_model::validation::DefaultUnsignedBlockValidator>())),
ordering_service_(std::make_shared<MockOnDemandOrderingService>()),
network_client_(std::make_shared<transport::MockOdOsNotification>()) {

auto proposal_factory = std::make_unique<MockUnsafeProposalFactory>();
OrderingGateFixture()
: block_factory_(std::make_shared<shared_model::proto::ProtoBlockFactory>(
std::make_unique<
shared_model::validation::DefaultUnsignedBlockValidator>())),
ordering_service_(
std::make_shared<NiceMock<MockOnDemandOrderingService>>()),
network_client_(
std::make_shared<NiceMock<transport::MockOdOsNotification>>()) {
auto proposal_factory =
std::make_unique<NiceMock<MockUnsafeProposalFactory>>();
proposal_factory_ = proposal_factory.get();
ordering_gate_ = std::make_shared<OnDemandOrderingGate>(ordering_service_, network_client_,
rounds_.get_observable(),
std::move(proposal_factory),
initial_round_);

// to suppress "uninteresting" gmock warnings
EXPECT_CALL(*ordering_service_, onCollaborationOutcome(_)).Times(AtLeast(0));
EXPECT_CALL(*network_client_, onRequestProposal(_)).Times(AtLeast(0));
EXPECT_CALL(*proposal_factory_, unsafeCreateProposal(_, _, _)).Times(AtLeast(0));
ordering_gate_ =
std::make_shared<OnDemandOrderingGate>(ordering_service_,
network_client_,
rounds_.get_observable(),
std::move(proposal_factory),
initial_round_);
}
};

Expand All @@ -52,10 +52,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) {

iroha::protocol::Block block;
if (protobuf_mutator::libfuzzer::LoadProtoInput(true, data, size, &block)) {
auto iroha_block = ordering_gate_fixture.block_factory_->createBlock(std::move(block));
if (auto result = boost::get<iroha::expected::Value<std::unique_ptr<shared_model::interface::Block>>>(
&iroha_block)) {
ordering_gate_fixture.rounds_.get_subscriber().on_next(std::move(result->value));
auto iroha_block =
ordering_gate_fixture.block_factory_->createBlock(std::move(block));
if (auto result = boost::get<iroha::expected::Value<
std::unique_ptr<shared_model::interface::Block>>>(&iroha_block)) {
ordering_gate_fixture.rounds_.get_subscriber().on_next(
std::move(result->value));
}
}

Expand Down
63 changes: 63 additions & 0 deletions test/fuzzing/ordering_service_fixture.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef IROHA_ORDERING_SERVICE_FIXTURE_HPP
#define IROHA_ORDERING_SERVICE_FIXTURE_HPP

#include <memory>

#include <gtest/gtest.h>
#include <libfuzzer/libfuzzer_macro.h>

#include "backend/protobuf/proto_transport_factory.hpp"
#include "backend/protobuf/transaction.hpp"
#include "interfaces/iroha_internal/transaction_batch_factory_impl.hpp"
#include "interfaces/iroha_internal/transaction_batch_impl.hpp"
#include "interfaces/iroha_internal/transaction_batch_parser_impl.hpp"
#include "module/shared_model/interface/mock_transaction_batch_factory.hpp"
#include "module/shared_model/interface_mocks.hpp"
#include "module/shared_model/validators/validators.hpp"
#include "ordering/impl/on_demand_ordering_service_impl.hpp"
#include "ordering/impl/on_demand_os_server_grpc.hpp"

using namespace testing;
using namespace iroha::ordering;
using namespace iroha::ordering::transport;

namespace fuzzing {
struct OrderingServiceFixture {
std::shared_ptr<OnDemandOsServerGrpc::TransportFactoryType>
transaction_factory_;
std::shared_ptr<shared_model::interface::TransactionBatchParser>
batch_parser_;
std::shared_ptr<NiceMock<MockTransactionBatchFactory>>
transaction_batch_factory_;
NiceMock<shared_model::validation::MockValidator<
shared_model::interface::Transaction>> *transaction_validator_;

OrderingServiceFixture() {
// fuzzing target is intended to run many times (~millions) so any
// additional output slows it down significantly
spdlog::set_level(spdlog::level::err);

auto transaction_validator =
std::make_unique<NiceMock<shared_model::validation::MockValidator<
shared_model::interface::Transaction>>>();
transaction_validator_ = transaction_validator.get();
transaction_factory_ =
std::make_shared<shared_model::proto::ProtoTransportFactory<
shared_model::interface::Transaction,
shared_model::proto::Transaction>>(
std::move(transaction_validator));

batch_parser_ = std::make_shared<
shared_model::interface::TransactionBatchParserImpl>();
transaction_batch_factory_ =
std::make_shared<NiceMock<MockTransactionBatchFactory>>();
}
};
} // namespace fuzzing

#endif // IROHA_ORDERING_SERVICE_FIXTURE_HPP
36 changes: 36 additions & 0 deletions test/fuzzing/request_proposal_fuzz.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#include "ordering_service_fixture.hpp"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) {
static fuzzing::OrderingServiceFixture fixture;

if (size < 1) {
return 0;
}

std::shared_ptr<OnDemandOrderingServiceImpl> ordering_service_;
std::shared_ptr<OnDemandOsServerGrpc> server_;

auto proposal_factory = std::make_unique<MockUnsafeProposalFactory>();
ordering_service_ = std::make_shared<OnDemandOrderingServiceImpl>(
data[0], std::move(proposal_factory));
server_ = std::make_shared<OnDemandOsServerGrpc>(
ordering_service_,
fixture.transaction_factory_,
fixture.batch_parser_,
fixture.transaction_batch_factory_);

proto::ProposalRequest request;
if (protobuf_mutator::libfuzzer::LoadProtoInput(
true, data + 1, size - 1, &request)) {
grpc::ServerContext context;
proto::ProposalResponse response;
server_->RequestProposal(&context, &request, &response);
}

return 0;
}
36 changes: 36 additions & 0 deletions test/fuzzing/send_batches_fuzz.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#include "ordering_service_fixture.hpp"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) {
static fuzzing::OrderingServiceFixture fixture;

if (size < 1) {
return 0;
}

std::shared_ptr<OnDemandOrderingServiceImpl> ordering_service_;
std::shared_ptr<OnDemandOsServerGrpc> server_;

auto proposal_factory = std::make_unique<MockUnsafeProposalFactory>();
ordering_service_ = std::make_shared<OnDemandOrderingServiceImpl>(
data[0], std::move(proposal_factory));
server_ = std::make_shared<OnDemandOsServerGrpc>(
ordering_service_,
fixture.transaction_factory_,
fixture.batch_parser_,
fixture.transaction_batch_factory_);

proto::BatchesRequest request;
if (protobuf_mutator::libfuzzer::LoadProtoInput(
true, data + 1, size - 1, &request)) {
grpc::ServerContext context;
google::protobuf::Empty response;
server_->SendBatches(&context, &request, &response);
}

return 0;
}

0 comments on commit f23dcea

Please sign in to comment.