aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Tokarev <mjt@tls.msk.ru>2025-08-24 03:05:32 +0300
committerMichael Tokarev <mjt@tls.msk.ru>2025-09-03 10:57:50 +0300
commit606978500c3d18fb89a49844f253097b17f757de (patch)
treefc7481b4c95653093b457af6214299165bf88dcb
parent1566b8c8df9e8603f5d03cc1a7708c4ecfda0897 (diff)
downloadqemu-606978500c3d18fb89a49844f253097b17f757de.zip
qemu-606978500c3d18fb89a49844f253097b17f757de.tar.gz
qemu-606978500c3d18fb89a49844f253097b17f757de.tar.bz2
block/curl: fix curl internal handles handling
block/curl.c uses CURLMOPT_SOCKETFUNCTION to register a socket callback. According to the documentation, this callback is called not just with application-created sockets but also with internal curl sockets, - and for such sockets, user data pointer is not set by the application, so the result qemu crashing. Pass BDRVCURLState directly to the callback function as user pointer, instead of relying on CURLINFO_PRIVATE. This problem started happening with update of libcurl from 8.9 to 8.10 -- apparently with this change curl started using private handles more. (CURLINFO_PRIVATE is used in one more place, in curl_multi_check_completion() - it might need a similar fix too) Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3081 Cc: qemu-stable@qemu.org Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
-rw-r--r--block/curl.c7
1 files changed, 2 insertions, 5 deletions
diff --git a/block/curl.c b/block/curl.c
index 5467678..00b949e 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -162,13 +162,9 @@ static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
void *userp, void *sp)
{
- BDRVCURLState *s;
- CURLState *state = NULL;
+ BDRVCURLState *s = userp;
CURLSocket *socket;
- curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **)&state);
- s = state->s;
-
socket = g_hash_table_lookup(s->sockets, GINT_TO_POINTER(fd));
if (!socket) {
socket = g_new0(CURLSocket, 1);
@@ -605,6 +601,7 @@ static void curl_attach_aio_context(BlockDriverState *bs,
assert(!s->multi);
s->multi = curl_multi_init();
s->aio_context = new_context;
+ curl_multi_setopt(s->multi, CURLMOPT_SOCKETDATA, s);
curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb);
curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, s);
curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, curl_timer_cb);