diff options
author | Adam Chelminski <adam.chelminski@mongodb.com> | 2016-08-17 17:11:10 -0400 |
---|---|---|
committer | Adam Chelminski <adam.chelminski@mongodb.com> | 2016-08-19 11:11:23 -0400 |
commit | 1a3d60af4d27d72e15637bb43510fe1b592a6c43 (patch) | |
tree | 7ab2edd2291f41a2fe37262f32e37618de5f0388 /src | |
parent | 76f1c8254147f806fef11e9dedabee359422c02b (diff) | |
download | mongo-1a3d60af4d27d72e15637bb43510fe1b592a6c43.tar.gz |
SERVER-13517 Internal client validates BSON in all command responses and when reading from cursor in DBClientCursor
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/client/dbclientcursor.cpp | 14 | ||||
-rw-r--r-- | src/mongo/client/dbclientcursor.h | 1 | ||||
-rw-r--r-- | src/mongo/db/dbmessage.h | 4 | ||||
-rw-r--r-- | src/mongo/rpc/legacy_reply.cpp | 10 | ||||
-rw-r--r-- | src/mongo/rpc/legacy_reply.h | 2 |
5 files changed, 28 insertions, 3 deletions
diff --git a/src/mongo/client/dbclientcursor.cpp b/src/mongo/client/dbclientcursor.cpp index 2c48dbce514..2b534defbba 100644 --- a/src/mongo/client/dbclientcursor.cpp +++ b/src/mongo/client/dbclientcursor.cpp @@ -264,6 +264,7 @@ void DBClientCursor::commandDataReceived() { QueryResult::View qr = batch.m.singleData().view2ptr(); batch.data = qr.data(); + batch.remainingBytes = qr.dataLen(); } void DBClientCursor::dataReceived(bool& retry, string& host) { @@ -302,6 +303,7 @@ void DBClientCursor::dataReceived(bool& retry, string& host) { batch.nReturned = qr.getNReturned(); batch.pos = 0; batch.data = qr.data(); + batch.remainingBytes = qr.dataLen(); _client->checkResponse(batch.data, batch.nReturned, &retry, &host); // watches for "not master" @@ -344,9 +346,19 @@ BSONObj DBClientCursor::next() { uassert(13422, "DBClientCursor next() called but more() is false", batch.pos < batch.nReturned); - batch.pos++; + uassert(ErrorCodes::InvalidBSON, + "Got invalid BSON from external server while reading from cursor.", + validateBSON(batch.data, + batch.remainingBytes, + enableBSON1_1 ? BSONVersion::kV1_1 : BSONVersion::kV1_0) + .isOK()); + BSONObj o(batch.data); + + batch.pos++; batch.data += o.objsize(); + batch.remainingBytes -= o.objsize(); + /* todo would be good to make data null at end of batch for safety */ return o; } diff --git a/src/mongo/client/dbclientcursor.h b/src/mongo/client/dbclientcursor.h index b8592738921..c0367b830a0 100644 --- a/src/mongo/client/dbclientcursor.h +++ b/src/mongo/client/dbclientcursor.h @@ -212,6 +212,7 @@ public: int nReturned{0}; int pos{0}; const char* data{nullptr}; + int remainingBytes{0}; public: Batch() = default; diff --git a/src/mongo/db/dbmessage.h b/src/mongo/db/dbmessage.h index 7fabf117421..01530edd641 100644 --- a/src/mongo/db/dbmessage.h +++ b/src/mongo/db/dbmessage.h @@ -138,6 +138,10 @@ public: return storage().view(sizeof(Layout)); } + int32_t dataLen() const { + return msgdata().getLen() - sizeof(Layout); + } + protected: const ConstDataView& storage() const { return _storage; diff --git a/src/mongo/rpc/legacy_reply.cpp b/src/mongo/rpc/legacy_reply.cpp index e9af23dee9e..572a96d2dd2 100644 --- a/src/mongo/rpc/legacy_reply.cpp +++ b/src/mongo/rpc/legacy_reply.cpp @@ -33,6 +33,7 @@ #include <tuple> #include <utility> +#include "mongo/bson/bson_validate.h" #include "mongo/rpc/legacy_reply_builder.h" #include "mongo/rpc/metadata.h" #include "mongo/util/assert_util.h" @@ -67,6 +68,15 @@ LegacyReply::LegacyReply(const Message* message) : _message(std::move(message)) << qr.getStartingFrom(), qr.getStartingFrom() == 0); + if (serverGlobalParams.objcheck) { + uassert(ErrorCodes::InvalidBSON, + "Got legacy command reply with invalid BSON in the metadata field.", + validateBSON(qr.data(), + qr.dataLen(), + enableBSON1_1 ? BSONVersion::kV1_1 : BSONVersion::kV1_0) + .isOK()); + } + std::tie(_commandReply, _metadata) = uassertStatusOK(rpc::upconvertReplyMetadata(BSONObj(qr.data()))); diff --git a/src/mongo/rpc/legacy_reply.h b/src/mongo/rpc/legacy_reply.h index bfb366f1da2..7d3d222f59d 100644 --- a/src/mongo/rpc/legacy_reply.h +++ b/src/mongo/rpc/legacy_reply.h @@ -41,8 +41,6 @@ namespace rpc { /** * Immutable view of an OP_REPLY legacy-style command reply. - * - * TODO: BSON validation (SERVER-18167) */ class LegacyReply : public ReplyInterface { public: |