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

Avoid accessing `OpDebug` from other threads

    • Server Security
    • Fully Compatible
    • ALL
    • v7.1, v7.0
    • Security 2023-09-04, Security 2023-09-18
    • 5

      OpDebug is a non-synchronized structure, designed to hold debug information for an operation. This structure is not intended to be visible to any thread other than the one that is running the operation:

      /**
       * Returns a structure containing data used for profiling, accessed only by a thread
       * currently executing the operation context associated with this CurOp.
       */
      OpDebug& debug() {
          return _debug;
      }
      

      SERVER-74962 and SERVER-75265 introduced a non-thread-safe usage of OpDebug by having the operation thread write a state that is later accessed/read by any thread that calls into CurOp::reportState:

      StatusWith<CursorResponse> ClusterFind::runGetMore(OperationContext* opCtx, ...) {
          ...
          {
              CurOp::get(opCtx)->debug().nShards = pinnedCursor.getValue()->getNumRemotes();
              CurOp::get(opCtx)->debug().cursorid = cursorId;
              CurOp::get(opCtx)->debug().shouldOmitDiagnosticInformation =
                  pinnedCursor.getValue()->shouldOmitDiagnosticInformation();
              stdx::lock_guard<Client> lk(*opCtx->getClient());
              CurOp::get(opCtx)->setOriginatingCommand_inlock(
                  pinnedCursor.getValue()->getOriginatingCommand());
              CurOp::get(opCtx)->setGenericCursor_inlock(pinnedCursor.getValue().toGenericCursor());
          }
          ...
      }
      
      void CurOp::reportState(BSONObjBuilder* builder, ...) {
          ...
          bool omitAndRedactInformation = CurOp::get(opCtx)->debug().shouldOmitDiagnosticInformation;
          builder->append("redacted", omitAndRedactInformation);
          ...
      }
      

      The above is identified by TSAN as a read-after-write data race. A possible fix is to move any shared data into CurOp, currently protected by the Client lock.

            Assignee:
            erwin.pe@mongodb.com Erwin Pe
            Reporter:
            amirsaman.memaripour@mongodb.com Amirsaman Memaripour
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: