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

CSFLE: Uninitialized _processHandle in mongo_crypt_v1.dll destructor

    • Type: Icon: Bug Bug
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 8.0.3
    • Component/s: Field Level Encryption
    • Server Security
    • Windows
    • Hide

      Steps to reproduce (reproducable in Java):

      1. Download the Java Application from GitHub linked in the Quick-Start documentation to encrypt a document with Client-Side Field Level Encryption (CSFLE).
      2. Update the mongodb-driver-sync to 4.11.2 and mongodb-crypt to 1.8 versions  in the pom.xml file.
      3. Add logging println(“Connection closed succesfully”) after mongoClientSecure.close() in the InsertEncryptedDocument class.
      4. Run the application on Windows and observe the crash during the cleanup of mongo_crypt_v1.dll.

      Spawn host image on evergreen windows-2022-latest-large:

      • OS Name: Microsoft Windows Server 2022 Datacenter
      • OS Version: 10.0.20348 N/A Build 20348

      mongo_crypt_shared: mongo_crypt_shared_v1-windows-x86_64-enterprise-8.0.3
      JDK: Oracle OpenJDK 21

      Show
      Steps to reproduce (reproducable in Java): Download the  Java Application  from GitHub linked in the  Quick-Start documentation to encrypt a document with Client-Side Field Level Encryption (CSFLE). Update the mongodb-driver-sync to 4.11.2 and mongodb-crypt to 1.8 versions  in the pom.xml file. Add logging println(“Connection closed succesfully”) after mongoClientSecure.close() in the InsertEncryptedDocument class. Run the application on Windows and observe the crash during the cleanup of mongo_crypt_v1.dll . Spawn host image on evergreen windows-2022-latest-large: OS Name: Microsoft Windows Server 2022 Datacenter OS Version: 10.0.20348 N/A Build 20348 mongo_crypt_shared: mongo_crypt_shared_v1-windows-x86_64-enterprise-8.0.3 JDK: Oracle OpenJDK 21
    • Security 2024-12-23

      An issue has been observed in MongoDB's Java Driver when configured with Automatic CSFLE on Windows. Invoking mongoClient.close() causes the application to crash, halting execution abruptly.

      Investigation Details:

      1. Reproduction Context:

      • The crash occurs when mongoClientSecure.close() is invoked in a Java application using Automatic CSFLE.
      • The Java Driver uses JNA (Java Native Access) to call mongocrypt_destroy from libmongocrypt.dll. This, in turn, unloads mongo_crypt_v1.dll.
      • The unloading process is initiated here: libmongocrypt/src/mongocrypt.c.

      2. Root Cause Analysis:

      The crash is traced to the SymbolHandler implementation in mongo_crypt_v1.dll, specifically when the destructor attempts to access _processHandle.

      The issue originates from the following code snippet in the constructor of SymbolHandler that initializes the debugging symbols using the Windows API:

      if (!SymInitializeW(handle, symbolPath.c_str(), TRUE)) {
          auto ec = lastSystemError();
          LOGV2_ERROR(
              31443, "Stack trace initialization failed", "error"_attr = errorMessage(ec));
          return;
      }

      If SymInitializeW fails, _processHandle remains uninitialized, leaving it in an invalid state. When _processHandle is accessed during the destructor, it causes an exception.

      3. Error Manifestation:

      Debugging on Windows via attached debugger to a running JVM (java.exe) process reveals the stack trace below, indicating the failure occurs when the uninitialized _processHandle is accessed, specifically within the SymbolHandler::getHandle() method during the destructor process (the relevant code can be viewed here):

      KernelBase.dll!RaiseException()
      vcruntime140.dll!_CxxThrowException(void * pExceptionObject=0x0000006a5b9fcf40, const _s__ThrowInfo * pThrowInfo) Line 75
          at d:\a01\_work\43\s\src\vctools\crt\vcruntime\src\eh\throw.cpp(75)
      mongo_crypt_v1.dll!boost::throw_exception<boost::bad_optional_access>(const boost::bad_optional_access & e) Line 165
          at C:\data\mci\2efe95839f2d5820eba4ee313ef101d7\src\src\third_party\boost\boost\throw_exception.hpp(165)
      [Inline Frame] mongo_crypt_v1.dll!boost::optional<void *>::value() Line 1300
          at C:\data\mci\2efe95839f2d5820eba4ee313ef101d7\src\src\third_party\boost\boost\optional\optional.hpp(1300)
      [Inline Frame] mongo_crypt_v1.dll!mongo::`anonymous-namespace'::SymbolHandler::getHandle() Line 112
          at C:\data\mci\2efe95839f2d5820eba4ee313ef101d7\src\src\mongo\util\stacktrace_windows.cpp(112)
      [Inline Frame] mongo_crypt_v1.dll!mongo::`anonymous-namespace'::SymbolHandler::{dtor}() Line 108
          at C:\data\mci\2efe95839f2d5820eba4ee313ef101d7\src\src\mongo\util\stacktrace_windows.cpp(108)
      mongo_crypt_v1.dll!`mongo::`anonymous namespace'::SymbolHandler::instance'::`2'::`dynamic atexit destructor for 'globalSymbolHandler''()
      ucrtbase.dll!<lambda>(void)()
      ucrtbase.dll!__crt_seh_guarded_call<int>::operator()<<lambda_7777bce6b2f8c936911f934f8298dc43>,<lambda>(void) &,<lambda_3883c3dff614d5e0c5f61bb1ac94921c>>()
      ucrtbase.dll!_execute_onexit_table()
      mongo_crypt_v1.dll!dllmain_crt_process_detach(const bool is_terminating=false) Line 182
          at d:\a01\_work\43\s\src\vctools\crt\vcstartup\src\startup\dll_dllmain.cpp(182)
      mongo_crypt_v1.dll!dllmain_dispatch(HINSTANCE__ * const instance=0x00007fffbd110000, const unsigned long reason=0x00000000, void * const reserved=0x0000000000000000) Line 293
          at d:\a01\_work\43\s\src\vctools\crt\vcstartup\src\startup\dll_dllmain.cpp(293)
      ntdll.dll!LdrpCallInitRoutine()
      ntdll.dll!LdrpProcessDetachNode()
      ntdll.dll!LdrpUnloadNode()
      ntdll.dll!LdrpDecrementModuleLoadCountEx()
      ntdll.dll!LdrUnloadDll()
      KernelBase.dll!FreeLibrary()
      jna5956855386430033609.dll!00007fffc2a75e39()
      jna5956855386430033609.dll!00007fffc2a78dc8()
      jna2721185145343487717.dll!00007ff83cf59161()
      jna2721185145343487717.dll!00007ff83cf5894b()
      jna2721185145343487717.dll!00007ff83cf585da()
      jna2721185145343487717.dll!00007ff83cf4e5a4()
      jna2721185145343487717.dll!00007ff83cf58b34()
      jna2721185145343487717.dll!00007ff83cf5928e()
      00000191eea60816()
      00000191dd90e448()
      0000006a5b9fef78()
      00000191ce02b2d0()
      0000000000000002()
      0000000000000001()
      00000191eea6011f()
      0000006a5b9fef20()
      00000191c963c198()
      0000000000000004()
      00000191c963d950()  

      4. Additional Context:

      It seems SymInitializeW returns false due to pre-existing symbol handler initialization in the JVM process. Microsoft documentation warns against calling SymInitializeW multiple times on the same process unless SymCleanup is called first. The JVM may have initialized dbghelp.dll for its own symbol resolution needs before mongo_crypt_v1.dll is loaded.

      Possible Fix
      Add validation checks in the mongo_crypt_v1.dll destructor to ensure _processHandle is initialized before use.

      Impact:
      Applications on Windows integrating MongoDB's Java Driver with Automatic CSFLE are affected. This issue may also appear in other drivers utilizing similar configurations.

            Assignee:
            adam.rayner@mongodb.com Adam Rayner
            Reporter:
            slav.babanin@mongodb.com Slav Babanin
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: