summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Cooper <adam.cooper@mongodb.com>2019-10-25 22:59:35 +0000
committerevergreen <evergreen@mongodb.com>2019-10-25 22:59:35 +0000
commitf04f573d25ed7c2e8c4e99d2a12ff828033ccf30 (patch)
treed36c3c0551e8b976b12431d937c5cdd71bf7197c
parentccb49c1ce100d918662937e7bb275a3efb7b680a (diff)
downloadmongo-f04f573d25ed7c2e8c4e99d2a12ff828033ccf30.tar.gz
SERVER-44064 Perform explicit cast on MessageCompressorManager parameter
(cherry picked from commit ffc6e38bc90750cc639317fc713e7bc4e0bf596e)
-rw-r--r--src/mongo/transport/message_compressor_manager.cpp5
-rw-r--r--src/mongo/transport/message_compressor_manager_test.cpp22
2 files changed, 26 insertions, 1 deletions
diff --git a/src/mongo/transport/message_compressor_manager.cpp b/src/mongo/transport/message_compressor_manager.cpp
index 6930f881a2c..c96a7f791f6 100644
--- a/src/mongo/transport/message_compressor_manager.cpp
+++ b/src/mongo/transport/message_compressor_manager.cpp
@@ -167,7 +167,10 @@ StatusWith<Message> MessageCompressorManager::decompressMessage(const Message& m
return {ErrorCodes::BadValue, "Decompressed message would be negative in size"};
}
- size_t bufferSize = compressionHeader.uncompressedSize + MsgData::MsgDataHeaderSize;
+ // Explicitly promote `uncompressedSize` to a 64-bit integer before addition in order to
+ // avoid potential overflow.
+ size_t bufferSize =
+ static_cast<size_t>(compressionHeader.uncompressedSize) + MsgData::MsgDataHeaderSize;
if (bufferSize > MaxMessageSizeBytes) {
return {ErrorCodes::BadValue,
"Decompressed message would be larger than maximum message size"};
diff --git a/src/mongo/transport/message_compressor_manager_test.cpp b/src/mongo/transport/message_compressor_manager_test.cpp
index 7d1011c91ae..4d46f1e5188 100644
--- a/src/mongo/transport/message_compressor_manager_test.cpp
+++ b/src/mongo/transport/message_compressor_manager_test.cpp
@@ -317,6 +317,28 @@ TEST(MessageCompressorManager, MessageSizeTooLarge) {
ASSERT_NOT_OK(status);
}
+TEST(MessageCompressorManager, MessageSizeMax32Bit) {
+ auto registry = buildRegistry();
+ MessageCompressorManager compManager(&registry);
+
+ auto badMessageBuffer = SharedBuffer::allocate(128);
+ MsgData::View badMessage(badMessageBuffer.get());
+ badMessage.setId(1);
+ badMessage.setResponseToMsgId(0);
+ badMessage.setOperation(dbCompressed);
+ badMessage.setLen(128);
+
+ DataRangeCursor cursor(badMessage.data(), badMessage.data() + badMessage.dataLen());
+ uassertStatusOK(cursor.writeAndAdvance<LittleEndian<int32_t>>(dbQuery));
+ uassertStatusOK(
+ cursor.writeAndAdvance<LittleEndian<int32_t>>(std::numeric_limits<int32_t>::max()));
+ uassertStatusOK(
+ cursor.writeAndAdvance<LittleEndian<uint8_t>>(registry.getCompressor("noop")->getId()));
+
+ auto status = compManager.decompressMessage(Message(badMessageBuffer), nullptr).getStatus();
+ ASSERT_NOT_OK(status);
+}
+
TEST(MessageCompressorManager, MessageSizeTooSmall) {
auto registry = buildRegistry();
MessageCompressorManager compManager(&registry);