From cfa10de6e60b4eb0fbaa39d8d5e3a3774ad47b95 Mon Sep 17 00:00:00 2001 From: Waley Chen Date: Mon, 7 Mar 2016 11:30:52 -0500 Subject: [PATCH] SERVER-22767 mongos segfault when invoking .explain() on certain operations --- jstests/noPassthrough/server22767.js | 21 +++++++++++++++++++++ src/mongo/client/parallel.cpp | 10 ++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 jstests/noPassthrough/server22767.js diff --git a/jstests/noPassthrough/server22767.js b/jstests/noPassthrough/server22767.js new file mode 100644 index 0000000000000..9b915ce0940b9 --- /dev/null +++ b/jstests/noPassthrough/server22767.js @@ -0,0 +1,21 @@ +// test that the mongos doesn't segfault when it receives malformed BSON +var st = new ShardingTest({shards:1}); +var testDB = st.getDB('test'); +testDB.test.insert({a:1}); + +try { + testDB.test.find({key: {$regex: 'abcd\0xyz'}}).explain(); +} catch (e) { + /* + * if the mongos segfaults, the error is the msg: + * "Error: error doing query: failed: network error while attempting to run command 'explain' on host '127.0.0.1:20014'" + * + * if the mongos doesn't segfault, the error is the object: + * "Error: explain failed: { + * "code" : 22, + * "ok" : 0, + * "errmsg" : "bson length doesn't match what we found in object with unknown _id" + * }" + */ + assert.eq(22, e.code); +} \ No newline at end of file diff --git a/src/mongo/client/parallel.cpp b/src/mongo/client/parallel.cpp index 37d2622538a46..23981d811ac6c 100644 --- a/src/mongo/client/parallel.cpp +++ b/src/mongo/client/parallel.cpp @@ -849,8 +849,14 @@ void ParallelSortClusteredCursor::finishInit(OperationContext* txn) { } throw; } else { - warning() << "db exception when finishing on " << shardId - << ", current connection state is " << mdata.toBSON() << causedBy(e); + // the InvalidBSON exception indicates that the BSON is malformed -> + // don't print/call "mdata.toBSON()" to avoid unexpected errors e.g. a segfault + if (e.getCode() == 22) + warning() << "bson is malformed :: db exception when finishing on " << shardId + << causedBy(e); + else + warning() << "db exception when finishing on " << shardId + << ", current connection state is " << mdata.toBSON() << causedBy(e); mdata.errored = true; throw; }