summaryrefslogtreecommitdiff
path: root/src/mongo/rpc
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2023-04-05 20:21:49 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-04-07 01:17:11 +0000
commit8f16e96a151a823b4db9a5527d108c7a054b419e (patch)
tree0b656ac7958485f9d5a3a84fe6b421ab14f9bda7 /src/mongo/rpc
parent759110fa276dc332c2dec26d71c7246f27ebc391 (diff)
downloadmongo-8f16e96a151a823b4db9a5527d108c7a054b419e.tar.gz
SERVER-75562 Enforce client metadata limit of 512 on non-internal clients
Diffstat (limited to 'src/mongo/rpc')
-rw-r--r--src/mongo/rpc/metadata/client_metadata.cpp11
-rw-r--r--src/mongo/rpc/metadata/client_metadata.h2
-rw-r--r--src/mongo/rpc/metadata/client_metadata_test.cpp25
3 files changed, 36 insertions, 2 deletions
diff --git a/src/mongo/rpc/metadata/client_metadata.cpp b/src/mongo/rpc/metadata/client_metadata.cpp
index 8bd250551cc..24971fbdadc 100644
--- a/src/mongo/rpc/metadata/client_metadata.cpp
+++ b/src/mongo/rpc/metadata/client_metadata.cpp
@@ -488,7 +488,7 @@ void ClientMetadata::setFromMetadataForOperation(OperationContext* opCtx, BSONEl
state.meta = std::move(inputMetadata);
}
-void ClientMetadata::setFromMetadata(Client* client, BSONElement& elem) {
+void ClientMetadata::setFromMetadata(Client* client, BSONElement& elem, bool isInternalClient) {
if (elem.eoo()) {
return;
}
@@ -502,6 +502,15 @@ void ClientMetadata::setFromMetadata(Client* client, BSONElement& elem) {
}
auto meta = ClientMetadata::readFromMetadata(elem);
+
+ if (!isInternalClient) {
+ uassert(ErrorCodes::ClientMetadataDocumentTooLarge,
+ str::stream() << "The client metadata document must be less than or equal to "
+ << kMaxMongoSMetadataDocumentByteLength << " bytes",
+ static_cast<uint32_t>(meta->_document.objsize()) <=
+ kMaxMongoSMetadataDocumentByteLength);
+ }
+
if (meta && isMongos()) {
// If we had a full ClientMetadata and we're on mongos, attach some additional client data.
meta->setMongoSMetadata(getHostNameCachedAndPort(),
diff --git a/src/mongo/rpc/metadata/client_metadata.h b/src/mongo/rpc/metadata/client_metadata.h
index 309eb5668e0..713fab5f819 100644
--- a/src/mongo/rpc/metadata/client_metadata.h
+++ b/src/mongo/rpc/metadata/client_metadata.h
@@ -230,7 +230,7 @@ public:
* This function is only valid to invoke if you are on the Client's thread. This function takes
* the Client lock.
*/
- static void setFromMetadata(Client* client, BSONElement& elem);
+ static void setFromMetadata(Client* client, BSONElement& elem, bool isInternalClient);
/**
* Set the ClientMetadata for the OperationContext by reading it from the given BSONElement.
diff --git a/src/mongo/rpc/metadata/client_metadata_test.cpp b/src/mongo/rpc/metadata/client_metadata_test.cpp
index d01507ba66a..b50a9a69185 100644
--- a/src/mongo/rpc/metadata/client_metadata_test.cpp
+++ b/src/mongo/rpc/metadata/client_metadata_test.cpp
@@ -387,4 +387,29 @@ TEST(ClientMetadataTest, TestEooElemAsValueToSetOpCtxMetadata) {
ASSERT_FALSE(clientMetaDataPtr);
}
+TEST(ClientMetadataTest, InternalClientLimit) {
+ auto svcCtx = ServiceContext::make();
+ svcCtx->registerClientObserver(std::make_unique<LockerNoopClientObserver>());
+ auto client = svcCtx->makeClient("ClientMetadataTest");
+
+ std::string tooLargeValue(600, 'x');
+
+ auto doc = BSON(kMetadataDoc << BSON(kDriver << BSON(kName << "n1" << kVersion << "v1")
+ << kOperatingSystem << BSON(kType << kUnknown)
+ << "extra" << tooLargeValue));
+ auto el = doc.firstElement();
+
+ // Succeeds because default limit is 1024 unless mongos (unit tests are not mongos)
+ ASSERT_OK(ClientMetadata::parse(el).getStatus());
+
+ // Throws since the document is too large
+ ASSERT_THROWS_CODE(ClientMetadata::setFromMetadata(client.get(), el, false),
+ DBException,
+ ErrorCodes::ClientMetadataDocumentTooLarge);
+
+
+ // Succeeds because internal client allows 1024
+ ASSERT_DOES_NOT_THROW(ClientMetadata::setFromMetadata(client.get(), el, true));
+}
+
} // namespace mongo