Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-8368

Possible deadlock between db mutex and ClientCursor::ccmutex during authorization in ClientCursor::eraseIfAuthorized?

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 2.4.0-rc1
    • Affects Version/s: 2.3.2
    • Component/s: Concurrency, Security
    • Labels:
      None

      In various types of operations, the ClientCursor::ccmutex is acquired after the db mutex. For example, during a get more, a read lock on the db mutex is acquired, then the ccmutex is acquired to look up a ClientCursor with a particular cursor id.

      Historically, a kill cursors ran by calling ClientCursor::erase() which acquired ClientCursor::ccmutex without a db mutex. (Any "in use" ClientCursor would be pinned and this function would fail before deleting it.)

      Currently, kill cursors calls ClientCursor::eraseIfAuthorized(), which acquires the ClientCursor::ccmutex and then checks getAuthorizationManager()->checkAuthorization(). It looks like some code paths from checkAuthorization() may acquire a db lock to read user documents from a database's system.users collection - in particular in _probeForPrivilege … AuthExternalState::getPrivilegeDocument. I'm not familiar enough with the auth code to know under what circumstances these code paths will be triggered. However, if ccmutex can be acquired before the db mutex a deadlock is possible (as stated above most other operations acquire the db mutex then the ccmutex).

      Could you let me know if I'm on the right tack with this?

            Assignee:
            spencer@mongodb.com Spencer Brody (Inactive)
            Reporter:
            aaron Aaron Staple
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: