From: Colin Walters Date: Wed, 18 Sep 2024 17:41:59 +0000 (-0400) Subject: curl: Make socket callback during cleanup into no-op X-Git-Tag: archive/raspbian/2024.8-1+rpi1^2^2~4 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=ff444b1610b9b5080700055295fc809ef1d52278;p=ostree.git curl: Make socket callback during cleanup into no-op Because curl_multi_cleanup may invoke callbacks, we effectively have some circular references going on here. See discussion in https://github.com/curl/curl/issues/14860 Basically what we do is the socket callback libcurl may invoke into a no-op when we detect we're finalizing. The data structures are owned by this object and not by the callbacks, and will be destroyed below. Note that e.g. g_hash_table_unref() may itself invoke callbacks, which is where some data is cleaned up. Signed-off-by: Colin Walters Origin: upstream, 2024.8, commit:4d755a85225ea0a02d4580d088bb8a97138cb040 Bug: https://github.com/ostreedev/ostree/issues/3299 Bug-Debian: https://bugs.debian.org/1082121 Gbp-Pq: Name curl-Make-socket-callback-during-cleanup-into-no-op.patch --- diff --git a/src/libostree/ostree-fetcher-curl.c b/src/libostree/ostree-fetcher-curl.c index 5808c451..1872974a 100644 --- a/src/libostree/ostree-fetcher-curl.c +++ b/src/libostree/ostree-fetcher-curl.c @@ -78,6 +78,7 @@ struct OstreeFetcher struct curl_slist *extra_headers; int tmpdir_dfd; bool force_anonymous; + bool finalizing; // Set if we're in the process of teardown char *custom_user_agent; guint32 opt_low_speed_limit; guint32 opt_low_speed_time; @@ -180,6 +181,15 @@ _ostree_fetcher_finalize (GObject *object) { OstreeFetcher *self = OSTREE_FETCHER (object); + // Because curl_multi_cleanup may invoke callbacks, we effectively have + // some circular references going on here. See discussion in + // https://github.com/curl/curl/issues/14860 + // Basically what we do is make most callbacks libcurl may invoke into no-ops when + // we detect we're finalizing. The data structures are owned by this object and + // not by the callbacks, and will be destroyed below. Note that + // e.g. g_hash_table_unref() may itself invoke callbacks, which is where + // some data is cleaned up. + self->finalizing = true; curl_multi_cleanup (self->multi); g_free (self->remote_name); g_free (self->tls_ca_db_path); @@ -529,6 +539,10 @@ sock_cb (CURL *easy, curl_socket_t s, int what, void *cbp, void *sockp) OstreeFetcher *fetcher = cbp; SockInfo *fdp = (SockInfo *)sockp; + // We do nothing if we're in the process of teardown; see below. + if (fetcher->finalizing) + return 0; + if (what == CURL_POLL_REMOVE) { if (!g_hash_table_remove (fetcher->sockets, fdp))