While simulating out-of-memory conditions in __wt_calloc, I triggered a use-after-free error in __session_open_cursor.
Sequence of events:
- __session_open_cursor calls __wt_open_cursor with the cursor pointer set to NULL (line 357)
- __wt_open_cursor partially succeeds, but has to return early because __wt_strdup() has an allocation failure (line 318). This causes the cursor to be closed and the pointer value to be freed.
- Back in __session_open_cursor, the err block is jumped to and the freed memory is accessed because the pointer is non-NULL (line 365)
Relevant code excerpted:
int __wt_open_cursor(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp) { WT_COLGROUP *colgroup; WT_DATA_SOURCE *dsrc; WT_DECL_RET; *cursorp = NULL; [ ..... snip ..... ] 316 if ((*cursorp)->uri == NULL && 317 (ret = __wt_strdup(session, uri, &(*cursorp)->uri)) != 0) 318 WT_TRET((*cursorp)->close(*cursorp)); return (ret); } static int __session_open_cursor(WT_SESSION *wt_session, const char *uri, WT_CURSOR *to_dup, const char *config, WT_CURSOR **cursorp) { WT_CURSOR *cursor; WT_DECL_RET; WT_SESSION_IMPL *session; cursor = *cursorp = NULL; [ ..... snip ..... ] 357 WT_ERR(__wt_open_cursor(session, uri, NULL, cfg, &cursor)); 358 if (to_dup != NULL) 359 WT_ERR(__wt_cursor_dup_position(to_dup, cursor)); 360 361 *cursorp = cursor; 363 if (0) { 364 err: if (cursor != NULL) 365 WT_TRET(cursor->close(cursor)); }
ASan report:
==9690== ERROR: AddressSanitizer: heap-use-after-free on address 0x603a001b2f50 at pc 0x2f5681e bp 0x7f3b572792f0 sp 0x7f3b572792e8 READ of size 8 at 0x603a001b2f50 thread T105 #0 0x2f5681d in __session_open_cursor /home/s/code/mongo/mongo/src/third_party/wiredtiger/src/session/session_api.c:365 #1 0x206e8c8 in mongo::WiredTigerSession::getCursor(std::string const&, unsigned long, bool) /home/s/code/mongo/mongo/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp:69 #2 0x206d16c in mongo::WiredTigerCursor::WiredTigerCursor(std::string const&, unsigned long, bool, mongo::OperationContext*) /home/s/code/mongo/mongo/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp:403 #3 0x205b360 in mongo::WiredTigerRecordStore::findRecord(mongo::OperationContext*, mongo::RecordId const&, mongo::RecordData*) const /home/s/code/mongo/mongo/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp:549 #4 0x1f43738 in mongo::KVCatalog::_findEntry(mongo::OperationContext*, mongo::StringData, mongo::RecordId*) const /home/s/code/mongo/mongo/src/mongo/db/storage/kv/kv_catalog.cpp:227 #5 0x1f439e3 in mongo::KVCatalog::getMetaData(mongo::OperationContext*, mongo::StringData) /home/s/code/mongo/mongo/src/mongo/db/storage/kv/kv_catalog.cpp:242 #6 0x1f4cfcd in mongo::KVCollectionCatalogEntry::_getMetaData(mongo::OperationContext*) const /home/s/code/mongo/mongo/src/mongo/db/storage/kv/kv_collection_catalog_entry.cpp:174 #7 0x1f17654 in mongo::BSONCollectionCatalogEntry::getCollectionOptions(mongo::OperationContext*) const /home/s/code/mongo/mongo/src/mongo/db/storage/bson_collection_catalog_entry.cpp:39 #8 0x185fee9 in mongo::mr::State::prepTempCollection() /home/s/code/mongo/mongo/src/mongo/db/commands/mr.cpp:405 #9 0x186e757 in mongo::mr::MapReduceFinishCommand::run(mongo::OperationContext*, std::string const&, mongo::BSONObj&, int, std::string&, mongo::BSONObjBuilder&) /home/s/code/mongo/mongo/src/mongo/db/commands/mr.cpp:1596 #10 0x190bf2b in mongo::Command::run(mongo::OperationContext*, mongo::rpc::RequestInterface const&, mongo::rpc::ReplyBuilderInterface*) /home/s/code/mongo/mongo/src/mongo/db/dbcommands.cpp:1316 #11 0x190b53f in mongo::Command::execCommand(mongo::OperationContext*, mongo::Command*, mongo::rpc::RequestInterface const&, mongo::rpc::ReplyBuilderInterface*) /home/s/code/mongo/mongo/src/mongo/db/dbcommands.cpp:1266 #12 0x180e691 in mongo::runCommands(mongo::OperationContext*, mongo::rpc::RequestInterface const&, mongo::rpc::ReplyBuilderInterface*) /home/s/code/mongo/mongo/src/mongo/db/commands.cpp:495 #13 0x1aba2c0 in mongo::(anonymous namespace)::receivedRpc(mongo::OperationContext*, mongo::Client&, mongo::DbResponse&, mongo::Message&) /home/s/code/mongo/mongo/src/mongo/db/instance.cpp:291 #14 0x1abb8e6 in mongo::assembleResponse(mongo::OperationContext*, mongo::Message&, mongo::DbResponse&, mongo::HostAndPort const&) /home/s/code/mongo/mongo/src/mongo/db/instance.cpp:509 #15 0x15b9862 in mongo::MyMessageHandler::process(mongo::Message&, mongo::AbstractMessagingPort*) /home/s/code/mongo/mongo/src/mongo/db/db.cpp:167 #16 0x2332e85 in mongo::PortMessageServer::handleIncomingMsg(void*) /home/s/code/mongo/mongo/src/mongo/util/net/message_server_port.cpp:229 #17 0x7f3b9b596b97 (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x18b97) #18 0x7f3b9a73c181 in start_thread /build/buildd/eglibc-2.19/nptl/pthread_create.c:312 #19 0x7f3b9a46947c in clone /build/buildd/eglibc-2.19/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:111 0x603a001b2f50 is located 144 bytes inside of 688-byte region [0x603a001b2ec0,0x603a001b3170) freed by thread T105 here: #0 0x7f3b9b59333a in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x1533a) #1 0x2ee51a7 in __wt_free_int /home/s/code/mongo/mongo/src/third_party/wiredtiger/src/os_posix/os_alloc.c:262 #2 0x2e7f56a in __wt_cursor_close /home/s/code/mongo/mongo/src/third_party/wiredtiger/src/cursor/cur_std.c:478 #3 0x2e4d721 in __curfile_close /home/s/code/mongo/mongo/src/third_party/wiredtiger/src/cursor/cur_file.c:380 #4 0x2f55d7b in __wt_open_cursor /home/s/code/mongo/mongo/src/third_party/wiredtiger/src/session/session_api.c:318 #5 0x2e8bfa6 in __wt_curtable_open /home/s/code/mongo/mongo/src/third_party/wiredtiger/src/cursor/cur_table.c:879 #6 0x2f55261 in __wt_open_cursor /home/s/code/mongo/mongo/src/third_party/wiredtiger/src/session/session_api.c:247 #7 0x2f56763 in __session_open_cursor /home/s/code/mongo/mongo/src/third_party/wiredtiger/src/session/session_api.c:357 #8 0x206e8c8 in mongo::WiredTigerSession::getCursor(std::string const&, unsigned long, bool) /home/s/code/mongo/mongo/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp:69 #9 0x206d16c in mongo::WiredTigerCursor::WiredTigerCursor(std::string const&, unsigned long, bool, mongo::OperationContext*) /home/s/code/mongo/mongo/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp:403 #10 0x205b360 in mongo::WiredTigerRecordStore::findRecord(mongo::OperationContext*, mongo::RecordId const&, mongo::RecordData*) const /home/s/code/mongo/mongo/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp:549 #11 0x1f43738 in mongo::KVCatalog::_findEntry(mongo::OperationContext*, mongo::StringData, mongo::RecordId*) const /home/s/code/mongo/mongo/src/mongo/db/storage/kv/kv_catalog.cpp:227 #12 0x1f439e3 in mongo::KVCatalog::getMetaData(mongo::OperationContext*, mongo::StringData) /home/s/code/mongo/mongo/src/mongo/db/storage/kv/kv_catalog.cpp:242 #13 0x1f4cfcd in mongo::KVCollectionCatalogEntry::_getMetaData(mongo::OperationContext*) const /home/s/code/mongo/mongo/src/mongo/db/storage/kv/kv_collection_catalog_entry.cpp:174 #14 0x1f17654 in mongo::BSONCollectionCatalogEntry::getCollectionOptions(mongo::OperationContext*) const /home/s/code/mongo/mongo/src/mongo/db/storage/bson_collection_catalog_entry.cpp:39 #15 0x185fee9 in mongo::mr::State::prepTempCollection() /home/s/code/mongo/mongo/src/mongo/db/commands/mr.cpp:405 #16 0x186e757 in mongo::mr::MapReduceFinishCommand::run(mongo::OperationContext*, std::string const&, mongo::BSONObj&, int, std::string&, mongo::BSONObjBuilder&) /home/s/code/mongo/mongo/src/mongo/db/commands/mr.cpp:1596 #17 0x190bf2b in mongo::Command::run(mongo::OperationContext*, mongo::rpc::RequestInterface const&, mongo::rpc::ReplyBuilderInterface*) /home/s/code/mongo/mongo/src/mongo/db/dbcommands.cpp:1316 #18 0x190b53f in mongo::Command::execCommand(mongo::OperationContext*, mongo::Command*, mongo::rpc::RequestInterface const&, mongo::rpc::ReplyBuilderInterface*) /home/s/code/mongo/mongo/src/mongo/db/dbcommands.cpp:1266 #19 0x180e691 in mongo::runCommands(mongo::OperationContext*, mongo::rpc::RequestInterface const&, mongo::rpc::ReplyBuilderInterface*) /home/s/code/mongo/mongo/src/mongo/db/commands.cpp:495 #20 0x1aba2c0 in mongo::(anonymous namespace)::receivedRpc(mongo::OperationContext*, mongo::Client&, mongo::DbResponse&, mongo::Message&) /home/s/code/mongo/mongo/src/mongo/db/instance.cpp:291 #21 0x1abb8e6 in mongo::assembleResponse(mongo::OperationContext*, mongo::Message&, mongo::DbResponse&, mongo::HostAndPort const&) /home/s/code/mongo/mongo/src/mongo/db/instance.cpp:509 #22 0x15b9862 in mongo::MyMessageHandler::process(mongo::Message&, mongo::AbstractMessagingPort*) /home/s/code/mongo/mongo/src/mongo/db/db.cpp:167 #23 0x2332e85 in mongo::PortMessageServer::handleIncomingMsg(void*) /home/s/code/mongo/mongo/src/mongo/util/net/message_server_port.cpp:229 #24 0x7f3b9b596b97 (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x18b97) previously allocated by thread T105 here: #0 0x7f3b9b5934e5 in calloc (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x154e5) #1 0x2ee4380 in __wt_calloc /home/s/code/mongo/mongo/src/third_party/wiredtiger/src/os_posix/os_alloc.c:64 #2 0x2e4d977 in __wt_curfile_create /home/s/code/mongo/mongo/src/third_party/wiredtiger/src/cursor/cur_file.c:427 #3 0x2e4ea42 in __wt_curfile_open /home/s/code/mongo/mongo/src/third_party/wiredtiger/src/cursor/cur_file.c:526 #4 0x2f5585e in __wt_open_cursor /home/s/code/mongo/mongo/src/third_party/wiredtiger/src/session/session_api.c:281 #5 0x2e8bfa6 in __wt_curtable_open /home/s/code/mongo/mongo/src/third_party/wiredtiger/src/cursor/cur_table.c:879 #6 0x2f55261 in __wt_open_cursor /home/s/code/mongo/mongo/src/third_party/wiredtiger/src/session/session_api.c:247 #7 0x2f56763 in __session_open_cursor /home/s/code/mongo/mongo/src/third_party/wiredtiger/src/session/session_api.c:357 #8 0x206e8c8 in mongo::WiredTigerSession::getCursor(std::string const&, unsigned long, bool) /home/s/code/mongo/mongo/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp:69 #9 0x206d16c in mongo::WiredTigerCursor::WiredTigerCursor(std::string const&, unsigned long, bool, mongo::OperationContext*) /home/s/code/mongo/mongo/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp:403 #10 0x205b360 in mongo::WiredTigerRecordStore::findRecord(mongo::OperationContext*, mongo::RecordId const&, mongo::RecordData*) const /home/s/code/mongo/mongo/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp:549 #11 0x1f43738 in mongo::KVCatalog::_findEntry(mongo::OperationContext*, mongo::StringData, mongo::RecordId*) const /home/s/code/mongo/mongo/src/mongo/db/storage/kv/kv_catalog.cpp:227 #12 0x1f439e3 in mongo::KVCatalog::getMetaData(mongo::OperationContext*, mongo::StringData) /home/s/code/mongo/mongo/src/mongo/db/storage/kv/kv_catalog.cpp:242 #13 0x1f4cfcd in mongo::KVCollectionCatalogEntry::_getMetaData(mongo::OperationContext*) const /home/s/code/mongo/mongo/src/mongo/db/storage/kv/kv_collection_catalog_entry.cpp:174 #14 0x1f17654 in mongo::BSONCollectionCatalogEntry::getCollectionOptions(mongo::OperationContext*) const /home/s/code/mongo/mongo/src/mongo/db/storage/bson_collection_catalog_entry.cpp:39 #15 0x185fee9 in mongo::mr::State::prepTempCollection() /home/s/code/mongo/mongo/src/mongo/db/commands/mr.cpp:405 #16 0x186e757 in mongo::mr::MapReduceFinishCommand::run(mongo::OperationContext*, std::string const&, mongo::BSONObj&, int, std::string&, mongo::BSONObjBuilder&) /home/s/code/mongo/mongo/src/mongo/db/commands/mr.cpp:1596 #17 0x190bf2b in mongo::Command::run(mongo::OperationContext*, mongo::rpc::RequestInterface const&, mongo::rpc::ReplyBuilderInterface*) /home/s/code/mongo/mongo/src/mongo/db/dbcommands.cpp:1316 #18 0x190b53f in mongo::Command::execCommand(mongo::OperationContext*, mongo::Command*, mongo::rpc::RequestInterface const&, mongo::rpc::ReplyBuilderInterface*) /home/s/code/mongo/mongo/src/mongo/db/dbcommands.cpp:1266 #19 0x180e691 in mongo::runCommands(mongo::OperationContext*, mongo::rpc::RequestInterface const&, mongo::rpc::ReplyBuilderInterface*) /home/s/code/mongo/mongo/src/mongo/db/commands.cpp:495 #20 0x1aba2c0 in mongo::(anonymous namespace)::receivedRpc(mongo::OperationContext*, mongo::Client&, mongo::DbResponse&, mongo::Message&) /home/s/code/mongo/mongo/src/mongo/db/instance.cpp:291 #21 0x1abb8e6 in mongo::assembleResponse(mongo::OperationContext*, mongo::Message&, mongo::DbResponse&, mongo::HostAndPort const&) /home/s/code/mongo/mongo/src/mongo/db/instance.cpp:509 #22 0x15b9862 in mongo::MyMessageHandler::process(mongo::Message&, mongo::AbstractMessagingPort*) /home/s/code/mongo/mongo/src/mongo/db/db.cpp:167 #23 0x2332e85 in mongo::PortMessageServer::handleIncomingMsg(void*) /home/s/code/mongo/mongo/src/mongo/util/net/message_server_port.cpp:229 #24 0x7f3b9b596b97 (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x18b97) Thread T105 created by T0 here: #0 0x7f3b9b588b5b in __interceptor_pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.0+0xab5b) #1 0x2332575 in mongo::PortMessageServer::accepted(std::shared_ptr<mongo::Socket>, long long) /home/s/code/mongo/mongo/src/mongo/util/net/message_server_port.cpp:148 #2 0x2327b16 in mongo::Listener::initAndListen() /home/s/code/mongo/mongo/src/mongo/util/net/listen.cpp:351 #3 0x2332895 in mongo::PortMessageServer::run() /home/s/code/mongo/mongo/src/mongo/util/net/message_server_port.cpp:176 #4 0x15af712 in mongo::_initAndListen(int) /home/s/code/mongo/mongo/src/mongo/db/db.cpp:589 #5 0x15afb33 in mongo::initAndListen(int) /home/s/code/mongo/mongo/src/mongo/db/db.cpp:594 #6 0x15b1304 in mongoDbMain(int, char**, char**) /home/s/code/mongo/mongo/src/mongo/db/db.cpp:823 #7 0x15afedd in main /home/s/code/mongo/mongo/src/mongo/db/db.cpp:639 #8 0x7f3b9a390ec4 in __libc_start_main /build/buildd/eglibc-2.19/csu/libc-start.c:287
Version: 6c49d69bbae5d8807fc205dbca12eecf1a60258b
- is depended on by
-
SERVER-19282 WiredTiger changes in MongoDB 3.1.6
- Closed
- links to