-
-
Notifications
You must be signed in to change notification settings - Fork 6.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Double-free when using HTTPS with tunneling proxy #7982
Comments
Note for the repro that on Windows curl_global_init must use win32 flag (unless manually initializing winsock), suggest changing to CURL_GLOBAL_DEFAULT. The first free is here when curl_easy_cleanup -> Curl_free_request_state is called: Lines 2198 to 2205 in 9e560d1
data->req.p.http == conn->connect_state which is probably the problem Then I get an access violation when curl_multi_cleanup -> conn_shutdown is called and it tries to dereference conn->connect_state->prot_save: Lines 739 to 746 in 9e560d1
|
I think it should be discouraged, even if I also think that the code at least once tried to make sure that it would handle it. I'll make a PR and propose this addition to the
It should of course still not cause a crash. |
Easy handles that are used by the multi interface should be removed from the multi handle before they are cleaned up. Reported-by: Stephen M. Coakley Ref: #7982
I've managed to convert @sagebind's code into a new libcurl test case that reproduces this problem. Working on a fix. |
... to prevent a lingering pointer that would lead to a double-free. Added test 1939 to verify. Reported-by: Stephen M. Coakley Fixes #7982
Add a drop handler that guarantees that `curl_multi_remove_handle` is always called on easy handles added to a multi handle before the easy handle is dropped. Based on curl/curl#7982, we should not be allowing users to drop a previously attached handle without first calling `curl_multi_remove_handle`. In curl versions between 7.77 and 7.80 this could cause a crash under certain circumstances. While this will likely be fixed in the next curl version, it is still recommended to not allow this, plus we must still handle this case for users who may not have updated to a patched libcurl. I'm not totally happy with how this is implemented as it adds an `Arc::clone` call every time an easy handle is added to a multi handle, but I couldn't think of a better way of guaranteeing this behavior without breaking API changes. Fixes #421.
#7986 fixes this issue in my tests |
Fixes it for me as well, no more access violation in Windows |
#7986 fixed my issues downstream as well. Thanks for the quick fix! |
Add a drop handler that guarantees that `curl_multi_remove_handle` is always called on easy handles added to a multi handle before the easy handle is dropped. Based on curl/curl#7982, we should not be allowing users to drop a previously attached handle without first calling `curl_multi_remove_handle`. In curl versions between 7.77 and 7.80 this could cause a crash under certain circumstances. While this will likely be fixed in the next curl version, it is still recommended to not allow this, plus we must still handle this case for users who may not have updated to a patched libcurl. I'm not totally happy with how this is implemented as it adds an `Arc::clone` call every time an easy handle is added to a multi handle, but I couldn't think of a better way of guaranteeing this behavior without breaking API changes. Fixes #421.
I did this
Run a program using libcurl such as the following example:
The program crashes with the following output:
When running the example program through a debugger the program appears to crash at this line:
curl/lib/url.c
Line 793 in 9db25d2
Relevant stack trace from my debugger:
I'm not totally sure if this is specifically related to proxies, as I can only reproduce when nghttp2 is enabled and using HTTPS and using a proxy, but @iiibui who originally brought the issue to my attention could reproduce with other scenarios as well.
I believe in all scenarios, rearranging the cleanup calls to close the multi handle first and then the easy handle avoids the issue. The documentation for
curl_multi_cleanup
definitely recommends doing it in the order that I used, but it is unclear how important the order is. Is it a suggestion? Is it undefined behavior to cleanup in the reverse order? The docs don't say. I'm also not callingcurl_multi_remove_handle
at all, but it seems that it is called automatically bycurl_easy_cleanup
:curl/lib/url.c
Lines 378 to 382 in 9db25d2
Note this also seems similar to #7236, which was supposedly fixed.
I expected the following
The program should exit without error.
curl_easy_cleanup
on a handle without callingcurl_multi_remove_handle
first is undefined behavior, then I feel like the docs should say this more explicitly. The source code seems to expect people to not do this.curl_easy_cleanup
without callingcurl_multi_remove_handle
, then this is bug introduced in 51c0ebc. Everything works just fine without callingcurl_multi_remove_handle
on versions prior to that commit that I tested.curl_easy_cleanup
is called beforecurl_multi_cleanup
or not. The phrase "should be" seems a bit non-committal. What happens if I do it out-of-order?I help maintain the Rust bindings for libcurl, so ultimately I just want to know what the rules are for these calls so we can enforce them in the bindings.
curl/libcurl version
I can reproduce this on the latest
master
commit (9db25d2 as of writing) but usinggit bisect
I identified 51c0ebc as the offending commit where this issue started.I am configuring curl as follows:
operating system
Windows 10 under WSL2 (Ubuntu-flavored), however the original reporter of the issue reproduced on CentOS 7.3.1611.
The text was updated successfully, but these errors were encountered: