summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2016-01-08 15:47:18 -0500
committerBenety Goh <benety@mongodb.com>2016-01-12 10:10:58 -0500
commit28fe476b7e7e8d43461f20384b7072cd83ad30b7 (patch)
tree87b8f5692169cf960d52b34ceb08218aac9ca28e
parentee1daeddef9e19b6879add2e0082bb0300447f02 (diff)
downloadmongo-28fe476b7e7e8d43461f20384b7072cd83ad30b7.tar.gz
SERVER-22109 validate index spec namespace in applyOperation_inlock
(cherry picked from commit 51f0cfa865fe090a5208d5bff47faa5fbe6a92c1)
-rw-r--r--jstests/core/apply_ops1.js41
-rw-r--r--src/mongo/db/repl/oplog.cpp15
2 files changed, 56 insertions, 0 deletions
diff --git a/jstests/core/apply_ops1.js b/jstests/core/apply_ops1.js
index cd2b57216e8..430af6b62a3 100644
--- a/jstests/core/apply_ops1.js
+++ b/jstests/core/apply_ops1.js
@@ -45,6 +45,47 @@
'applyOps should fail on non-"n" operation type with empty "ns" field value'
);
+ // Missing 'o' field value in an operation of type 'i' on 'system.indexes' collection.
+ assert.commandFailedWithCode(
+ db.adminCommand({applyOps: [{op: 'i', ns: db.getName() + '.system.indexes'}]}),
+ 4, // ErrorCodes.NoSuchKey
+ 'applyOps should fail on system.indexes insert operation without "o" field');
+
+ // Non-object 'o' field value in an operation of type 'i' on 'system.indexes' collection.
+ assert.commandFailedWithCode(
+ db.adminCommand({applyOps: [{op: 'i', ns: db.getName() + '.system.indexes', o: 'bar'}]}),
+ 14, // ErrorCodes.TypeMismatch
+ 'applyOps should fail on system.indexes insert operation with non-object "o" field');
+
+ // Missing 'ns' field in index spec.
+ assert.commandFailedWithCode(
+ db.adminCommand({applyOps: [{op: 'i', ns: db.getName() + '.system.indexes', o: {
+ key: {a: 1},
+ name: 'a_1',
+ }}]}),
+ 4, // ErrorCodes.NoSuchKey
+ 'applyOps should fail on system.indexes insert operation with missing index namespace');
+
+ // Non-string 'ns' field in index spec.
+ assert.commandFailedWithCode(
+ db.adminCommand({applyOps: [{op: 'i', ns: db.getName() + '.system.indexes', o: {
+ ns: 12345,
+ key: {a: 1},
+ name: 'a_1',
+ }}]}),
+ 14, // ErrorCodes.TypeMismatch
+ 'applyOps should fail on system.indexes insert operation with non-string index namespace');
+
+ // Invalid 'ns' field in index spec.
+ assert.commandFailedWithCode(
+ db.adminCommand({applyOps: [{op: 'i', ns: db.getName() + '.system.indexes', o: {
+ ns: 'invalid_namespace',
+ key: {a: 1},
+ name: 'a_1',
+ }}]}),
+ 73, // ErrorCodes.InvalidNamespace
+ 'applyOps should fail on system.indexes insert operation with invalid index namespace');
+
// Valid 'ns' field value in unknown operation type 'x'.
assert.commandFailed(
db.adminCommand({applyOps: [{op: 'x', ns: t.getFullName()}]}),
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index d33a9814f9c..1688a5be578 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -39,6 +39,7 @@
#include <boost/thread/recursive_mutex.hpp>
+#include "mongo/bson/util/bson_extract.h"
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_manager.h"
@@ -633,6 +634,20 @@ bool applyOperation_inlock(OperationContext* txn,
const char* p = strchr(ns, '.');
if (p && nsToCollectionSubstring(p) == "system.indexes") {
+ uassert(ErrorCodes::NoSuchKey,
+ str::stream() << "Missing expected index spec in field 'o': " << op,
+ !fieldO.eoo());
+ uassert(ErrorCodes::TypeMismatch,
+ str::stream() << "Expected object for index spec in field 'o': " << op,
+ fieldO.isABSONObj());
+
+ std::string indexNs;
+ uassertStatusOK(bsonExtractStringField(o, "ns", &indexNs));
+ const NamespaceString indexNss(indexNs);
+ uassert(ErrorCodes::InvalidNamespace,
+ str::stream() << "Invalid namespace in index spec: " << op,
+ indexNss.isValid());
+
if (o["background"].trueValue()) {
Lock::TempRelease release(txn->lockState());
if (txn->lockState()->isLocked()) {