diff options
author | David Hows <howsdav@gmail.com> | 2015-07-31 16:22:46 +1000 |
---|---|---|
committer | David Hows <david.hows@mongodb.com> | 2015-09-24 09:06:41 +1000 |
commit | 8efa1322b11574c7d4286cef56e937718aa5e2a1 (patch) | |
tree | 8a38fdbb1834f3b1e52d82c7fd173888bfe80baf | |
parent | 08eacba75fb15e397222f20af0bf48b26b54a0d5 (diff) | |
download | mongo-8efa1322b11574c7d4286cef56e937718aa5e2a1.tar.gz |
SERVER-19671 - Null chars in namespaces cause issues
-rw-r--r-- | jstests/noPassthroughWithMongod/newcollection2.js | 7 | ||||
-rw-r--r-- | src/mongo/db/commands/apply_ops.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/repl/oplog.cpp | 8 |
3 files changed, 15 insertions, 4 deletions
diff --git a/jstests/noPassthroughWithMongod/newcollection2.js b/jstests/noPassthroughWithMongod/newcollection2.js index 86d5e9f7a3a..da13f6eadf2 100644 --- a/jstests/noPassthroughWithMongod/newcollection2.js +++ b/jstests/noPassthroughWithMongod/newcollection2.js @@ -8,3 +8,10 @@ db.createCollection( baseName, {size:0x1FFC0000-0x10-8192} ); var v = db[ baseName ].validate(); printjson( v ); assert( v.valid ); + +// Try creating collections with some invalid names and confirm that they +// don't crash MongoD. + +db.runCommand({ applyOps: [ { op: 'u', ns: 'a\0b' } ] }); +var res = db["a\0a"].insert({}); +assert(res.hasWriteError(), "A write to collection a\0a succceeded") diff --git a/src/mongo/db/commands/apply_ops.cpp b/src/mongo/db/commands/apply_ops.cpp index 7381d61dffc..6bab78adb6b 100644 --- a/src/mongo/db/commands/apply_ops.cpp +++ b/src/mongo/db/commands/apply_ops.cpp @@ -152,6 +152,10 @@ private: errmsg = str::stream() << "\"ns\" field is not a string: " << e.fieldName(); return false; } + if (nsElement.String().find('\0') != std::string::npos) { + errmsg = str::stream() << "namespaces cannot have embedded null characters"; + return false; + } if (*opType != 'n' && nsElement.String().empty()) { errmsg = str::stream() << "\"ns\" field value cannot be empty when op type is not 'n': " << e.fieldName(); diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index 341f55e8af1..90ce1efa98e 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -604,7 +604,7 @@ Status applyOperation_inlock(OperationContext* txn, if (fieldO.isABSONObj()) o = fieldO.embeddedObject(); - const char* ns = fieldNs.valuestrsafe(); + const StringData ns = fieldNs.valueStringData(); BSONObj o2; if (fieldO2.isABSONObj()) @@ -633,8 +633,7 @@ Status applyOperation_inlock(OperationContext* txn, if (*opType == 'i') { opCounters->gotInsert(); - const char* p = strchr(ns, '.'); - if (p && nsToCollectionSubstring(p) == "system.indexes") { + if (nsToCollectionSubstring(ns) == "system.indexes") { if (o["background"].trueValue()) { IndexBuilder* builder = new IndexBuilder(o); // This spawns a new thread and returns immediately. @@ -790,7 +789,8 @@ Status applyOperation_inlock(OperationContext* txn, // AuthorizationManager's logOp method registers a RecoveryUnit::Change // and to do so we need to have begun a UnitOfWork WriteUnitOfWork wuow(txn); - getGlobalAuthorizationManager()->logOp(txn, opType, ns, o, fieldO2.isABSONObj() ? &o2 : NULL); + getGlobalAuthorizationManager()->logOp( + txn, opType, ns.toString().c_str(), o, fieldO2.isABSONObj() ? &o2 : NULL); wuow.commit(); return Status::OK(); |