[SERVER-22697] DBException::toStatus exhibits undefined behavior when called on the exception thrown by a uassert Created: 17/Feb/16  Updated: 27/Aug/16  Resolved: 16/May/16

Status: Closed
Project: Core Server
Component/s: Internal Code
Affects Version/s: None
Fix Version/s: 3.3.8

Type: Bug Priority: Major - P3
Reporter: Andrew Morrow (Inactive) Assignee: Andrew Morrow (Inactive)
Resolution: Done Votes: 0
Labels: undefined-sanitizer
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Backwards Compatibility: Fully Compatible
Operating System: ALL
Steps To Reproduce:

Run jstests/core/updatel.js under ubsan.

Sprint: Platforms 14 (05/13/16), Platforms 15 (06/03/16)
Participants:

 Description   

If an exception thrown by uassert is caught as a DBException, and DBException::toStatus is called, it casts the numeric code to the ErrorCodes::Error type, even thought the uassert value is not a member of the enumeration, which is undefined behavior.

MongoDFixture:job0] src/mongo/base/status.cpp:44:32: runtime error: load of value 34412, which is not a valid value for type 'ErrorCodes::Error'
[MongoDFixture:job0]     #0 0x1026bd7 in mongo::Status::Status(mongo::ErrorCodes::Error, std::string, int) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/base/status.cpp:44:32
[MongoDFixture:job0]     #1 0x101b615 in mongo::DBException::toStatus() const /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/util/assert_util.h:117:9
[MongoDFixture:job0]     #2 0x12c900b in mongo::multiUpdate(mongo::OperationContext*, mongo::BatchItemRef const&, mongo::(anonymous namespace)::WriteOpResult*) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/commands/write_commands/batch_executor.cpp:1273:29
[MongoDFixture:job0]     #3 0x12c3b8e in mongo::WriteBatchExecutor::execUpdate(mongo::BatchItemRef const&, mongo::BSONObj*, mongo::WriteErrorDetail**) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/commands/write_commands/batch_executor.cpp:877:5
[MongoDFixture:job0]     #4 0x12c221e in mongo::WriteBatchExecutor::bulkExecute(mongo::BatchedCommandRequest const&, std::vector<mongo::BatchedUpsertDetail*, std::allocator<mongo::BatchedUpsertDetail*> >*, std::vector<mongo::WriteErrorDetail*, std::allocator<mongo::WriteErrorDetail*> >*) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/commands/write_commands/batch_executor.cpp:694:13
[MongoDFixture:job0]     #5 0x12c0616 in mongo::WriteBatchExecutor::executeBatch(mongo::BatchedCommandRequest const&, mongo::BatchedCommandResponse*) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/commands/write_commands/batch_executor.cpp:322:5
[MongoDFixture:job0]     #6 0x12d0449 in mongo::WriteCmd::run(mongo::OperationContext*, std::string const&, mongo::BSONObj&, int, std::string&, mongo::BSONObjBuilder&) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/commands/write_commands/write_commands.cpp:144:5
[MongoDFixture:job0]     #7 0x1307273 in mongo::Command::run(mongo::OperationContext*, mongo::rpc::RequestInterface const&, mongo::rpc::ReplyBuilderInterface*) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/dbcommands.cpp:1464:19
[MongoDFixture:job0]     #8 0x1305692 in mongo::Command::execCommand(mongo::OperationContext*, mongo::Command*, mongo::rpc::RequestInterface const&, mongo::rpc::ReplyBuilderInterface*) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/dbcommands.cpp:1332:18
[MongoDFixture:job0]     #9 0x1214624 in mongo::runCommands(mongo::OperationContext*, mongo::rpc::RequestInterface const&, mongo::rpc::ReplyBuilderInterface*) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/commands.cpp:498:9
[MongoDFixture:job0]     #10 0x14b4813 in mongo::(anonymous namespace)::receivedRpc(mongo::OperationContext*, mongo::Client&, mongo::DbResponse&, mongo::Message&) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/instance.cpp:304:9
[MongoDFixture:job0]     #11 0x14b4813 in mongo::assembleResponse(mongo::OperationContext*, mongo::Message&, mongo::DbResponse&, mongo::HostAndPort const&) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/instance.cpp:525
[MongoDFixture:job0]     #12 0x1012e54 in mongo::MyMessageHandler::process(mongo::Message&, mongo::AbstractMessagingPort*) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/db.cpp:173:17
[MongoDFixture:job0]     #13 0x1dcb6bd in mongo::PortMessageServer::handleIncomingMsg(void*) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/util/net/message_server_port.cpp:229:17
[MongoDFixture:job0]     #14 0x7fce5aabf6a9 in start_thread /build/buildd/glibc-2.21/nptl/pthread_create.c:333
[MongoDFixture:job0]     #15 0x7fce5a5ddeec in clone /build/buildd/glibc-2.21/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:109
[MongoDFixture:job0]



 Comments   
Comment by Githook User [ 16/May/16 ]

Author:

{u'username': u'acmorrow', u'name': u'Andrew Morrow', u'email': u'acm@mongodb.com'}

Message: SERVER-23826 SERVER-22697 Allow arbitrary error codes without undefined behavior
Branch: master
https://github.com/mongodb/mongo/commit/5ec034bbce9d2f0778b5c236d10b80a746356d6e

Comment by Andrew Morrow (Inactive) [ 18/Feb/16 ]

Yeah, pretty unfortunate. For this and all other ubsan issues, we do need to consider whether we actually care about that class of UB. Potentially, if we really disagree, we could disable a particular check. However, it doesn't leave me feeling too good about things if we do that - it still really truly is UB, and that leaves us open to future compiler hijinks.

Comment by Andy Schwerin [ 17/Feb/16 ]

This basically means we have to stop using enum type inside Status, I think. What a hassle.

Generated at Thu Feb 08 04:01:11 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.