summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiangyu Yao <xiangyu.yao@mongodb.com>2018-03-22 14:09:42 -0400
committerXiangyu Yao <xiangyu.yao@mongodb.com>2018-03-23 13:43:26 -0400
commitbfd40e8a7f4d741785a0742e17a1e20027b9f3b4 (patch)
tree9d935f0fedda0dddfd2f3233c7ea1e48ee71b250
parent4bb6f1da8c89567c6038b3390e7b034fcbaf18d0 (diff)
downloadmongo-bfd40e8a7f4d741785a0742e17a1e20027b9f3b4.tar.gz
SERVER-33854 Avoid accessing invalid memory in applyOps
-rw-r--r--jstests/core/apply_ops_without_ns.js10
-rw-r--r--src/mongo/db/repl/apply_ops.cpp2
-rw-r--r--src/mongo/db/repl/oplog.cpp6
3 files changed, 14 insertions, 4 deletions
diff --git a/jstests/core/apply_ops_without_ns.js b/jstests/core/apply_ops_without_ns.js
new file mode 100644
index 00000000000..a16c54b8f99
--- /dev/null
+++ b/jstests/core/apply_ops_without_ns.js
@@ -0,0 +1,10 @@
+// @tags: [requires_non_retryable_commands]
+
+(function() {
+ 'use strict';
+
+ // SERVER-33854: This should fail and not cause any invalid memory access.
+ assert.commandFailed(db.adminCommand({
+ applyOps: [{'op': 'c', 'ns': 'admin.$cmd', 'o': {applyOps: [{'op': 'i', 'o': {x: 1}}]}}]
+ }));
+})();
diff --git a/src/mongo/db/repl/apply_ops.cpp b/src/mongo/db/repl/apply_ops.cpp
index d460f037e40..d19bddb5197 100644
--- a/src/mongo/db/repl/apply_ops.cpp
+++ b/src/mongo/db/repl/apply_ops.cpp
@@ -76,7 +76,7 @@ bool _areOpsCrudOnly(const BSONObj& applyOpCmd) {
BSONElement& fieldOp = fields[1];
const char* opType = fieldOp.valuestrsafe();
- const StringData ns = fieldNs.valueStringData();
+ const StringData ns = fieldNs.valuestrsafe();
// All atomic ops have an opType of length 1.
if (opType[0] == '\0' || opType[1] != '\0')
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index eeb62f5303e..d72a2c3c7eb 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -1319,7 +1319,7 @@ Status applyOperation_inlock(OperationContext* opCtx,
UpdateLifecycleImpl updateLifecycle(requestNss);
request.setLifecycle(&updateLifecycle);
- const StringData ns = fieldNs.valueStringData();
+ const StringData ns = fieldNs.valuestrsafe();
writeConflictRetry(opCtx, "applyOps_upsert", ns, [&] {
WriteUnitOfWork wuow(opCtx);
// If this is an atomic applyOps (i.e: `haveWrappingWriteUnitOfWork` is true),
@@ -1369,7 +1369,7 @@ Status applyOperation_inlock(OperationContext* opCtx,
timestamp = fieldTs.timestamp();
}
- const StringData ns = fieldNs.valueStringData();
+ const StringData ns = fieldNs.valuestrsafe();
auto status = writeConflictRetry(opCtx, "applyOps_update", ns, [&] {
WriteUnitOfWork wuow(opCtx);
if (timestamp != Timestamp::min()) {
@@ -1444,7 +1444,7 @@ Status applyOperation_inlock(OperationContext* opCtx,
timestamp = fieldTs.timestamp();
}
- const StringData ns = fieldNs.valueStringData();
+ const StringData ns = fieldNs.valuestrsafe();
writeConflictRetry(opCtx, "applyOps_delete", ns, [&] {
WriteUnitOfWork wuow(opCtx);
if (timestamp != Timestamp::min()) {