[SERVER-73007] CURL_OPT_SEEKFUNCTION not set for multi-pass authentication Created: 18/Jan/23  Updated: 29/Oct/23  Resolved: 26/Apr/23

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: 7.1.0-rc0, 4.4.22, 5.0.18, 7.0.0-rc1, 6.0.7

Type: Bug Priority: Major - P3
Reporter: Gabriel Marks Assignee: Mark Benvenuto
Resolution: Fixed Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Backports
Problem/Incident
Related
Backwards Compatibility: Fully Compatible
Operating System: ALL
Backport Requested:
v7.0, v6.3, v6.0, v5.0, v4.4
Sprint: Security 2023-01-23, Security 2023-05-01
Participants:
Case:
Linked BF Score: 161

 Description   

We have observed the error CURLE_SEND_FAIL_REWIND occurring during authentication. This error occurs when data that has already been sent to the authentication server needs to be resent, which can happen as part of some multi-pass authentication methods (source: https://curl.se/libcurl/c/CURLOPT_SEEKFUNCTION.html), but there is no seek/ioctl function set to allow rewinding to the data that needs to be sent. To fix this, we need to define a CURL_OPT_SEEKFUNCTION so that we can correctly rewind.



 Comments   
Comment by Martin 'JaMa' Jansa [ 22/Sep/23 ]

I've noticed build failure for 32bit targets after this commit was backported to v4.4 branch:

src/mongo/util/net/http_client_curl.cpp: In function 'size_t mongo::{anonymous}::ReadMemoryCallback(char*, size_t, size_t, void*)':
src/mongo/util/net/http_client_curl.cpp:172:21: error: no matching function for call to 'min(size_t, long unsigned int)'
  172 |             std::min(size * nitems, static_cast<unsigned long>(bufReader->remaining()));
      |             ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I guess you should cast the first param from size_t to unsigned instead of unsigned from remaining() to unsigned long or change. Unless you close this as https://jira.mongodb.org/browse/SERVER-74633 because 32bit support (and using correct types) isn't officially supported.

Comment by Githook User [ 04/May/23 ]

Author:

{'name': 'Mark Benvenuto', 'email': 'mark.benvenuto@mongodb.com', 'username': 'markbenvenuto'}

Message: SERVER-73007 CURL_OPT_SEEKFUNCTION for HTTP retry

(cherry picked from commit f872d0b4efeba4f45961fca175e9bb3c65675d5f)
Branch: v5.0
https://github.com/mongodb/mongo/commit/c439d99bced773b2c03df6d00d0b6dcea1409f74

Comment by Githook User [ 04/May/23 ]

Author:

{'name': 'Mark Benvenuto', 'email': 'mark.benvenuto@mongodb.com', 'username': 'markbenvenuto'}

Message: SERVER-73007 CURL_OPT_SEEKFUNCTION for HTTP retry

(cherry picked from commit f872d0b4efeba4f45961fca175e9bb3c65675d5f)
Branch: v6.0
https://github.com/mongodb/mongo/commit/98f42ab91cd9e944fb41edad4f3510d9b39741b4

Comment by Githook User [ 04/May/23 ]

Author:

{'name': 'Mark Benvenuto', 'email': 'mark.benvenuto@mongodb.com', 'username': 'markbenvenuto'}

Message: SERVER-73007 CURL_OPT_SEEKFUNCTION for HTTP retry

(cherry picked from commit f872d0b4efeba4f45961fca175e9bb3c65675d5f)
Branch: v4.4
https://github.com/mongodb/mongo/commit/754195c7b158eb47162f1776ba1a9692f9429a45

Comment by Githook User [ 04/May/23 ]

Author:

{'name': 'Mark Benvenuto', 'email': 'mark.benvenuto@mongodb.com', 'username': 'markbenvenuto'}

Message: SERVER-73007 CURL_OPT_SEEKFUNCTION for HTTP retry

(cherry picked from commit f872d0b4efeba4f45961fca175e9bb3c65675d5f)
Branch: v7.0
https://github.com/mongodb/mongo/commit/91df5330f70bb96c2ca5d29f7dfbbbcca3e16ab5

Comment by Githook User [ 26/Apr/23 ]

Author:

{'name': 'Mark Benvenuto', 'email': 'mark.benvenuto@mongodb.com', 'username': 'markbenvenuto'}

Message: SERVER-73007 CURL_OPT_SEEKFUNCTION for HTTP retry
Branch: master
https://github.com/mongodb/mongo/commit/f872d0b4efeba4f45961fca175e9bb3c65675d5f

Comment by Githook User [ 25/Apr/23 ]

Author:

{'name': 'Sviatlana Zuiko', 'email': 'sviatlana.zuiko@mongodb.com', 'username': 'szuiko'}

Message: Revert "SERVER-73007 CURL_OPT_SEEKFUNCTION for HTTP retry"

This reverts commit f69b49f1360cc8421346ee2e939feb4b736db6e3.
Branch: master
https://github.com/mongodb/mongo/commit/c01429db1722f1f26531e97073a8d6c5ed8182b0

Comment by Githook User [ 25/Apr/23 ]

Author:

{'name': 'Mark Benvenuto', 'email': 'mark.benvenuto@mongodb.com', 'username': 'markbenvenuto'}

Message: SERVER-73007 CURL_OPT_SEEKFUNCTION for HTTP retry
Branch: master
https://github.com/mongodb/mongo/commit/f69b49f1360cc8421346ee2e939feb4b736db6e3

Comment by Mark Benvenuto [ 15/Apr/23 ]

POC Branch: https://github.com/markbenvenuto/mongo/tree/http_rewind

Comment by Mark Benvenuto [ 15/Apr/23 ]

The belief is that this issue is caused by CURL connections getting timed out/disconnected. Then when curl tries to reuse the connection:

https://github.com/curl/curl/blob/f438ce099b15d433c2bbd0e1ddc8ab17ef924d76/lib/multi.c#L2435-L2444

It hits an error, calls Curl_retry_request which sets rewindbeforesend which eventually triggers this path: https://github.com/curl/curl/blob/f438ce099b15d433c2bbd0e1ddc8ab17ef924d76/lib/multi.c#L1788-L1798.

To fix this, we need to implement CURLOPT_SEEKFUNCTION. We should need only to seek to the start with SEEK_SET.

Per https://curl.se/libcurl/c/CURLOPT_SEEKFUNCTION.html

This function gets called by libcurl to seek to a certain position in the input stream and can be used to fast forward a file in a resumed upload (instead of reading all uploaded bytes with the normal read function/callback). It is also called to rewind a stream when data has already been sent to the server and needs to be sent again. This may happen when doing an HTTP PUT or POST with a multi-pass authentication method, or when an existing HTTP connection is reused too late and the server closes the connection.

(emphasis mine)

 

 

Generated at Thu Feb 08 06:23:23 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.