[SERVER-8486] Acquiring privileges on database "" (empty string) trips fassert Created: 08/Feb/13  Updated: 11/Jul/16  Resolved: 12/Feb/13

Status: Closed
Project: Core Server
Component/s: Security
Affects Version/s: 2.4.0-rc0
Fix Version/s: 2.4.0-rc1

Type: Bug Priority: Major - P3
Reporter: J Rassi Assignee: Eric Milkie
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
Operating System: ALL
Participants:

 Description   

Reproduce with the following (note cloneCollection is being called on invalid collection):

adminDb = db.getSiblingDB("admin")
testDb = db.getSiblingDB("test")
testDb.addUser({user:'readUser',pwd:'password',roles:['read']})
adminDb.addUser({user:'admin',pwd:'password',roles:['userAdminAnyDatabase','readWriteAnyDatabase']})
testDb.auth('readUser','password')
testDb.runCommand({cloneCollection:1})

When run against mongod --auth, version 2.4.0-rc0:

(gdb) b mongo::printStackTrace
Breakpoint 1 at 0x1005e89c7: file stacktrace.cpp, line 35.
(gdb) r
Starting program: /Users/rassi/work/mongo/mongod --auth
Reading symbols for shared libraries ++............................. done
Fri Feb  8 15:01:10.803 [initandlisten] MongoDB starting : pid=12325 port=27017 dbpath=/data/db/ 64-bit host=Rassi-MacBook-Pro.local
Fri Feb  8 15:01:10.803 [initandlisten] 
Fri Feb  8 15:01:10.803 [initandlisten] ** WARNING: soft rlimits too low. Number of files is 256, should be at least 1000
Fri Feb  8 15:01:10.803 [initandlisten] db version v2.4.0-rc0, pdfile version 4.5
Fri Feb  8 15:01:10.803 [initandlisten] git version: 09967e98e5d6280305d85553cdb2dd12e2e1e149
Fri Feb  8 15:01:10.803 [initandlisten] build info: Darwin Rassi-MacBook-Pro.local 12.0.0 Darwin Kernel Version 12.0.0: Sun Jun 24 23:00:16 PDT 2012; root:xnu-2050.7.9~1/RELEASE_X86_64 x86_64 BOOST_LIB_VERSION=1_49
Fri Feb  8 15:01:10.803 [initandlisten] allocator: tcmalloc
Fri Feb  8 15:01:10.803 [initandlisten] options: { auth: true }
Fri Feb  8 15:01:10.804 [initandlisten] journal dir=/data/db/journal
Fri Feb  8 15:01:10.804 [initandlisten] recover : no journal files present, no recovery needed
Fri Feb  8 15:01:10.821 [FileAllocator] allocating new datafile /data/db/local.ns, filling with zeroes...
Fri Feb  8 15:01:10.821 [FileAllocator] creating directory /data/db/_tmp
Fri Feb  8 15:01:10.841 [FileAllocator] done allocating datafile /data/db/local.ns, size: 16MB,  took 0.02 secs
Fri Feb  8 15:01:10.870 [FileAllocator] allocating new datafile /data/db/local.0, filling with zeroes...
Fri Feb  8 15:01:11.017 [FileAllocator] done allocating datafile /data/db/local.0, size: 64MB,  took 0.146 secs
Fri Feb  8 15:01:11.040 [initandlisten] command local.$cmd command: { create: "startup_log", size: 10485760, capped: true } ntoreturn:1 keyUpdates:0  reslen:37 219ms
Fri Feb  8 15:01:11.040 [websvr] admin web console waiting for connections on port 28017
Fri Feb  8 15:01:11.040 [initandlisten] waiting for connections on port 27017
Fri Feb  8 15:01:17.198 [initandlisten] connection accepted from 127.0.0.1:55978 #1 (1 connection now open)
Fri Feb  8 15:01:17.198 [conn1] note: no users configured in admin.system.users, allowing localhost access
Fri Feb  8 15:01:17.199 [FileAllocator] allocating new datafile /data/db/test.ns, filling with zeroes...
Fri Feb  8 15:01:17.219 [FileAllocator] done allocating datafile /data/db/test.ns, size: 16MB,  took 0.02 secs
Fri Feb  8 15:01:17.244 [FileAllocator] allocating new datafile /data/db/test.0, filling with zeroes...
Fri Feb  8 15:01:17.397 [FileAllocator] done allocating datafile /data/db/test.0, size: 64MB,  took 0.152 secs
Fri Feb  8 15:01:17.435 [FileAllocator] allocating new datafile /data/db/test.1, filling with zeroes...
Fri Feb  8 15:01:17.436 [conn1] build index test.system.users { _id: 1 }
Fri Feb  8 15:01:17.437 [conn1] build index done.  scanned 0 total records. 0 secs
Fri Feb  8 15:01:17.437 [conn1] build index test.system.users { user: 1, userSource: 1 }
Fri Feb  8 15:01:17.438 [conn1] build index done.  scanned 0 total records. 0 secs
Fri Feb  8 15:01:17.438 [conn1] insert test.system.users ninserted:1 keyUpdates:0 locks(micros) w:238855 238ms
Fri Feb  8 15:01:17.751 [FileAllocator] done allocating datafile /data/db/test.1, size: 128MB,  took 0.315 secs
Fri Feb  8 15:01:17.751 [FileAllocator] allocating new datafile /data/db/admin.ns, filling with zeroes...
Fri Feb  8 15:01:17.792 [FileAllocator] done allocating datafile /data/db/admin.ns, size: 16MB,  took 0.04 secs
Fri Feb  8 15:01:17.824 [FileAllocator] allocating new datafile /data/db/admin.0, filling with zeroes...
Fri Feb  8 15:01:17.982 [FileAllocator] done allocating datafile /data/db/admin.0, size: 64MB,  took 0.157 secs
Fri Feb  8 15:01:18.013 [FileAllocator] allocating new datafile /data/db/admin.1, filling with zeroes...
Fri Feb  8 15:01:18.014 [conn1] build index admin.system.users { _id: 1 }
Fri Feb  8 15:01:18.015 [conn1] build index done.  scanned 0 total records. 0 secs
Fri Feb  8 15:01:18.015 [conn1] build index admin.system.users { user: 1, userSource: 1 }
Fri Feb  8 15:01:18.016 [conn1] build index done.  scanned 0 total records. 0 secs
Fri Feb  8 15:01:18.016 [conn1] insert admin.system.users ninserted:1 keyUpdates:0  575ms
Fri Feb  8 15:01:18.016 [conn1]  authenticate db: test { authenticate: 1, nonce: "d3010b747fda1271", user: "readUser", key: "888e4bffc7c5b7ece679b3e01808040b" }
Fri Feb  8 15:01:18.017 [conn1]   Fatal Assertion 16255
[Switching to process 12325 thread 0x2103]
 
Breakpoint 1, mongo::printStackTrace (os=@0x7fff7b438f10) at stacktrace.cpp:35
35	    void printStackTrace( std::ostream& os ) {
(gdb) bt
#0  mongo::printStackTrace (os=@0x7fff7b438f10) at stacktrace.cpp:35
#1  0x00000001005c1ec7 in mongo::fassertFailed (msgid=16255) at assert_util.cpp:129
#2  0x000000010013250c in mongo::Lock::DBRead::lockOther (this=0x1105a1730, db=@0x101ebe258) at assert_util.h:195
#3  0x000000010013302f in mongo::Lock::DBRead::lockTop () at /Users/rassi/work/mongo/src/mongo/db/d_concurrency.cpp:601
#4  0x000000010013302f in mongo::Lock::DBRead::lockDB (this=0x101dd25f0, ns=@0x0) at d_concurrency.cpp:602
#5  0x0000000100134431 in mongo::Lock::DBRead::DBRead (this=0x101dd25f0, ns=@0x1105a1870) at d_concurrency.cpp:619
#6  0x00000001000d6195 in mongo::Client::ReadContext::ReadContext (this=0x101dd25f0, ns=@0x1105a19d0, path=@0x1011d3598) at client.cpp:233
#7  0x00000001000a7521 in mongo::StringData::StringData () at /Users/rassi/work/mongo/src/mongo/base/string_data.h:43
#8  0x00000001000a7521 in mongo::AuthExternalStateMongod::_findUser (this=0x101dd25f0, usersNamespace=@0x1105a19d0, query=@0x101ebe258, result=0x101ebe258) at auth_external_state_d.cpp:45
#9  0x00000001000a6cd9 in mongo::AuthExternalState::getPrivilegeDocument (this=0x1105a1c50, dbname=@0x1105a1c50, principalName=@0x101dd2730, result=0x1105a1c50) at auth_external_state.cpp:57
#10 0x00000001000ad94e in boost::scoped_ptr<mongo::AuthExternalState>::operator-> () at /Users/rassi/work/mongo/src/third_party/boost/boost/smart_ptr/scoped_ptr.hpp:129
#11 0x00000001000ad94e in mongo::AuthorizationManager::_acquirePrivilegesForPrincipalFromDatabase (this=0x101e7a6c0, dbname=@0x1105a1cf0, principal=@0x101dd2730) at authorization_manager.cpp:129
#12 0x00000001000adc76 in mongo::AuthorizationManager::_probeForPrivilege (this=0x101e7a6c0, privilege=@0x1105a1cf0) at authorization_manager.cpp:812
#13 0x00000001000addd1 in mongo::AuthorizationManager::checkAuthForPrivileges (this=0x101e7a6c0, privileges=@0x1105a1fc8) at authorization_manager.cpp:789
#14 0x0000000100140263 in mongo::Command::execCommand (c=0x100e013d0, client=@0x1105a2120, queryOptions=274342176, cmdns=0x1105a2120 "?\"Z\020\001", cmdObj=@0x1105a2178, result=@0x1105a2120, fromRepl=false) at dbcommands.cpp:1941
#15 0x0000000100141355 in mongo::_runCommands (ns=0x1105a22e0 "p#Z\020\001", _cmdobj=@0x1105a24f0, b=@0x1105a22e0, anObjBuilder=@0x1105a22e0, queryOptions=0, fromRepl=false) at dbcommands.cpp:2085
#16 0x00000001003e8c9e in mongo::runCommands (ns=0x101de9814 "test.$cmd", jsobj=@0x101dfa8f0, curop=@0x101dec300, b=@0x1105a2438, anObjBuilder=@0x1105a1c70, queryOptions=0) at query.cpp:46
#17 0x00000001003e94a1 in mongo::runQuery (m=@0x101dfa8f0, q=@0x4, curop=@0x1105a2920, result=@0x1105a2920) at query.cpp:944
#18 0x0000000100396a5f in receivedQuery [inlined] () at /Users/rassi/work/mongo/src/mongo/db/instance.cpp:262
#19 0x0000000100396a5f in mongo::assembleResponse (m=@0x1105a2b50, dbresponse=@0x1105a2cc0, remote=@0x1105a2b38) at instance.cpp:407
#20 0x000000010000c2e2 in mongo::MyMessageHandler::process (this=0x1105a2b50, m=@0x1105a2d60, port=0x1105a2d60, le=0x1105a2d60) at db.cpp:193
#21 0x00000001005de479 in boost::shared_ptr<mongo::Socket>::operator-> () at /Users/rassi/work/mongo/src/third_party/boost/boost/smart_ptr/shared_ptr.hpp:206
#22 0x00000001005de479 in mongo::PortMessageServer::handleIncomingMsg (arg=0x1105a2b50) at message_server_port.cpp:207
#23 0x000000010061b065 in thread_proxy (param=0x101e78240) at thread.cpp:121
#24 0x00007fff8c14b782 in _pthread_start ()
#25 0x00007fff8c1381c1 in thread_start ()
(gdb)



 Comments   
Comment by auto [ 12/Feb/13 ]

Author:

{u'date': u'2013-02-12T21:08:02Z', u'name': u'Eric Milkie', u'email': u'milkie@10gen.com'}

Message: SERVER-8486 prevent empty dbnames in command params from crashing auth'd mongod

The crux of the issue is that we don't do command param checking until after
we've set up auth, but for certain commands we need their params to set up auth.
This might be fixed/avoided if we had a more formalized structure for
sanitizing input to commands.
Branch: master
https://github.com/mongodb/mongo/commit/314f7d6ab6dd5969bd36778429375f7f4874bb3b

Comment by Eric Milkie [ 12/Feb/13 ]

Note: if execution ever should fall through to the auth code with an empty db, the error in the server looks like:

Tue Feb 12 16:03:13.094 [conn1] Privilege acquisition failed for readUser@test in database : empty database names are illegal (BadValue)

instead of an fassert like above.

The behavior with calling cloneCollection with an empty db now looks like:

> testDb.runCommand({cloneCollection:1})
{
	"assertion" : "bad 'cloneCollection' value",
	"assertionCode" : 16706,
	"errmsg" : "db assertion failure",
	"ok" : 0
}

Generated at Thu Feb 08 03:17:34 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.