diff options
author | Xiangyu Yao <xiangyu.yao@mongodb.com> | 2018-03-22 14:09:42 -0400 |
---|---|---|
committer | Xiangyu Yao <xiangyu.yao@mongodb.com> | 2018-03-23 13:43:26 -0400 |
commit | bfd40e8a7f4d741785a0742e17a1e20027b9f3b4 (patch) | |
tree | 9d935f0fedda0dddfd2f3233c7ea1e48ee71b250 | |
parent | 4bb6f1da8c89567c6038b3390e7b034fcbaf18d0 (diff) | |
download | mongo-bfd40e8a7f4d741785a0742e17a1e20027b9f3b4.tar.gz |
SERVER-33854 Avoid accessing invalid memory in applyOps
-rw-r--r-- | jstests/core/apply_ops_without_ns.js | 10 | ||||
-rw-r--r-- | src/mongo/db/repl/apply_ops.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/oplog.cpp | 6 |
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()) { |