[CDRIVER-3336] Uninitialised BSON reply when running command on wrong server with pinned session Created: 26/Aug/19  Updated: 28/Oct/23  Resolved: 28/Aug/19

Status: Closed
Project: C Driver
Component/s: libmongoc
Affects Version/s: None
Fix Version/s: 1.15.1

Type: Bug Priority: Major - P3
Reporter: Andreas Braun Assignee: Clyde Bazile III (Inactive)
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
is depended on by PHPC-1290 Support mongos pinning for sharded tr... Closed

 Description   

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().



 Comments   
Comment by Githook User [ 28/Aug/19 ]

Author:

{'name': 'Clyde Bazile', 'username': 'bazile-clyde', 'email': 'bazileclyde@gmail.com'}

Message: CDRIVER-3336 Uninitialised BSON reply on error
Branch: r1.15
https://github.com/mongodb/mongo-c-driver/commit/cf50d6315a581a3c96cb43ae46f87c7b762f24e2

Comment by Githook User [ 28/Aug/19 ]

Author:

{'name': 'Clyde Bazile', 'username': 'bazile-clyde', 'email': 'bazileclyde@gmail.com'}

Message: CDRIVER-3336 Uninitialised BSON reply on error
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/548f0752509e7679ba7e90b767888ad2891f59d5

Comment by Clyde Bazile III (Inactive) [ 26/Aug/19 ]

CR: https://mongodbcr.appspot.com/504600001/

Generated at Wed Feb 07 21:17:44 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.