Uploaded image for project: 'C Driver'
  1. C Driver
  2. CDRIVER-3336

Uninitialised BSON reply when running command on wrong server with pinned session

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 1.15.1
    • Affects Version/s: None
    • Component/s: libmongoc
    • None

      While testing the session pinning implementation for the PHP driver, I uncovered a case where we attempt to free an uninitialised BSON reply. This not only affects the PHP driver, but also libmongoc itself if _mongoc_client_command_with_opts ends up being called without a reply object.

      In _mongoc_client_command_with_opts it is assumed that the reply object is initialised if no server_stream was opened. Later in the function, the reply object is freed if no reply was passed to the function. If a reply was passed but not initialised, an empty bson object is created.

      However, the assumption that not getting back a server_stream means an initialised reply (see comment in line 1941) is wrong in one case: passing a serverId in the options along with a session that is pinned to a different server triggers an error condition in mongoc_cluster_stream_for_server, which then returns NULL. This leads us to an uninitialised reply which is assumed to be initialised by _mongoc_client_command_with_opts. I believe that mongoc_cluster_stream_for_server needs a call to _mongoc_bson_init_if_set (reply) if the server pinning check fails.

      To reproduce this, you need to pin a session to a server, then call mongoc_client_command_with_opts (or any other command function) with the session, as well as a server ID that is different from the one that the session is pinned to. Not passing a reply pointer to the function triggers the bug in libmongoc.

      In the case of the PHP driver, a reply pointer is passed, which phongo_execute_command expects to be initialised during _mongoc_client_command_with_opts and subsequently frees it. This is consistent with the documentation:

      reply is always initialized, and must be freed with bson_destroy().

            Assignee:
            clyde.bazile@mongodb.com Clyde Bazile III (Inactive)
            Reporter:
            andreas.braun@mongodb.com Andreas Braun
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: