diff options
author | jason.piao <jason.piao@mongodb.com> | 2019-06-24 16:32:53 -0400 |
---|---|---|
committer | jason.piao <jason.piao@mongodb.com> | 2019-07-11 17:49:02 -0400 |
commit | 09e14555877947afc5dac351a4c8632febd8ea03 (patch) | |
tree | 3865da95d7e026765439376b342b6dfa3e3883d3 /src | |
parent | 96f983169f2217dea3336f45df6bd59aef3a0714 (diff) | |
download | mongo-09e14555877947afc5dac351a4c8632febd8ea03.tar.gz |
SERVER-41796 OpMsg HandleRequest fuzzer
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/SConscript | 18 | ||||
-rw-r--r-- | src/mongo/db/op_msg_fuzzer.cpp | 118 |
2 files changed, 136 insertions, 0 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index 39cce30206b..6eef7683b2a 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -1854,3 +1854,21 @@ asioEnv.CppIntegrationTest( '$BUILD_DIR/mongo/util/version_impl', ], ) + +env.CppLibfuzzerTest( + target='op_msg_fuzzer', + source=[ + 'op_msg_fuzzer.cpp', + ], + LIBDEPS=[ + '$BUILD_DIR/mongo/db/auth/authmocks', + '$BUILD_DIR/mongo/db/auth/auth', + '$BUILD_DIR/mongo/base', + '$BUILD_DIR/mongo/db/service_context', + '$BUILD_DIR/mongo/db/service_context_d', + '$BUILD_DIR/mongo/transport/service_entry_point', + '$BUILD_DIR/mongo/transport/transport_layer_mock', + '$BUILD_DIR/mongo/db/repl/replmocks', + '$BUILD_DIR/mongo/unittest/unittest/', + ], +) diff --git a/src/mongo/db/op_msg_fuzzer.cpp b/src/mongo/db/op_msg_fuzzer.cpp new file mode 100644 index 00000000000..7a4d0b0fefa --- /dev/null +++ b/src/mongo/db/op_msg_fuzzer.cpp @@ -0,0 +1,118 @@ +/** + * Copyright (C) 2019-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#include "mongo/bson/timestamp.h" +#include "mongo/db/auth/authorization_manager_impl.h" +#include "mongo/db/auth/authorization_session_for_test.h" +#include "mongo/db/auth/authz_manager_external_state_local.h" +#include "mongo/db/auth/authz_manager_external_state_mock.h" +#include "mongo/db/client.h" +#include "mongo/db/logical_clock.h" +#include "mongo/db/logical_time.h" +#include "mongo/db/operation_context.h" +#include "mongo/db/repl/repl_client_info.h" +#include "mongo/db/repl/replication_coordinator_mock.h" +#include "mongo/db/service_context.h" +#include "mongo/db/service_entry_point_common.h" +#include "mongo/db/service_entry_point_mongod.h" +#include "mongo/platform/basic.h" +#include "mongo/transport/service_entry_point_impl.h" +#include "mongo/transport/session.h" +#include "mongo/transport/transport_layer_mock.h" +#include "mongo/unittest/unittest.h" + +extern "C" int LLVMFuzzerTestOneInput(const char* Data, size_t Size) { + static mongo::ServiceContext* serviceContext; + static mongo::ServiceContext::UniqueClient client; + static mongo::transport::TransportLayerMock transportLayer; + static mongo::transport::SessionHandle session; + static std::unique_ptr<mongo::AuthzManagerExternalStateMock> localExternalState; + static mongo::AuthzManagerExternalStateMock* externalState; + static std::unique_ptr<mongo::AuthorizationManagerImpl> localAuthzManager; + static mongo::AuthorizationManagerImpl* authzManager; + + static std::unique_ptr<mongo::repl::ReplicationCoordinatorMock> replCoord; + const static mongo::LogicalTime kInMemoryLogicalTime = + mongo::LogicalTime(mongo::Timestamp(3, 1)); + + const static auto ret = [&]() { + auto ret = mongo::runGlobalInitializers(0, {nullptr}, nullptr); + invariant(ret.isOK()); + + setGlobalServiceContext(mongo::ServiceContext::make()); + session = transportLayer.createSession(); + + serviceContext = mongo::getGlobalServiceContext(); + serviceContext->setServiceEntryPoint( + std::make_unique<mongo::ServiceEntryPointMongod>(serviceContext)); + client = serviceContext->makeClient("test", session); + // opCtx = serviceContext->makeOperationContext(client.get()); + + localExternalState = std::make_unique<mongo::AuthzManagerExternalStateMock>(); + externalState = localExternalState.get(); + localAuthzManager = std::make_unique<mongo::AuthorizationManagerImpl>( + std::move(localExternalState), + mongo::AuthorizationManagerImpl::InstallMockForTestingOrAuthImpl{}); + + authzManager = localAuthzManager.get(); + externalState->setAuthorizationManager(authzManager); + authzManager->setAuthEnabled(true); + mongo::AuthorizationManager::set(serviceContext, std::move(localAuthzManager)); + + replCoord = std::make_unique<mongo::repl::ReplicationCoordinatorMock>(serviceContext); + ASSERT_OK(replCoord->setFollowerMode(mongo::repl::MemberState::RS_PRIMARY)); + mongo::repl::ReplicationCoordinator::set(mongo::getGlobalServiceContext(), + std::move(replCoord)); + + return ret; + }(); + + if (Size < sizeof(mongo::MSGHEADER::Value)) { + return 0; + } + mongo::ServiceContext::UniqueOperationContext opCtx = + serviceContext->makeOperationContext(client.get()); + auto logicalClock = std::make_unique<mongo::LogicalClock>(serviceContext); + logicalClock->setClusterTimeFromTrustedSource(kInMemoryLogicalTime); + mongo::LogicalClock::set(serviceContext, std::move(logicalClock)); + + int new_size = Size + sizeof(int); + auto sb = mongo::SharedBuffer::allocate(new_size); + memcpy(sb.get(), &new_size, sizeof(int)); + memcpy(sb.get() + sizeof(int), Data, Size); + mongo::Message msg(std::move(sb)); + + try { + serviceContext->getServiceEntryPoint()->handleRequest(opCtx.get(), msg); + } catch (const mongo::AssertionException&) { + // We need to catch exceptions caused by invalid inputs + } + + return 0; +} |