-
Notifications
You must be signed in to change notification settings - Fork 249
Closed
Labels
Description
Multi::close
is not safe to use because it calls curl_multi_cleanup
on the raw CURLM
pointer, which in turn calls free
on the pointer. But Multi::close
only takes &self
so nothing prevents you from attempting to call other methods on a Multi
after you called close
, which will attempt to use the freed pointer.
Lines 699 to 706 in ecc9d80
/// Attempt to close the multi handle and clean up all associated resources. | |
/// | |
/// Cleans up and removes a whole multi stack. It does not free or touch any | |
/// individual easy handles in any way - they still need to be closed | |
/// individually. | |
pub fn close(&self) -> Result<(), MultiError> { | |
unsafe { cvt(curl_sys::curl_multi_cleanup(self.raw)) } | |
} |
In fact, using Multi::close
at all causes this, because the Drop
handler itself calls curl_multi_cleanup
.
I see two potential ways of fixing this:
- Change
Multi::close
to takeself
instead of&self
, which is probably the original intention of the API and reflects the libcurl behavior correctly. This change would be backwards-incompatible. - Add some sort of flag to our
Multi
struct indicating ifcurl_multi_cleanup
has been called successfully and do not callcurl_multi_cleanup
again if that flag is set. All public methods must be updated to check the flag and return an error if the flag is set before calling any libcurl functions. This has an unfortunate runtime cost, but keeps backwards compatibility.
This was discovered downstream by @DBLouis in sagebind/isahc#198.