From 8e2eced23436c832a858802423b4ea8b45cf403a Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Mon, 17 Aug 2026 14:18:50 +0200 Subject: [PATCH] multi: initialisation order When creating a multi handle, global_init() may not have been invoked that. There is a lazy check for this in easy_init() that trigger global_init(). Create the admin handle for a multi first, before any further operations, so easy_init() can trigger a global_init() when necessary. Closes #22606 --- lib/multi.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/multi.c b/lib/multi.c index 6413ccc7b6..429651430a 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -235,8 +235,23 @@ struct Curl_multi *Curl_multi_handle(uint32_t xfer_table_size, multi->magic = CURLMULTI_MAGIC_NUMBER; + /* Initialisation order is important here! + * easy_init() does a lazy check on curl_global_init() which sets + * up platform specific things we need. For example calling curlx_pnow() + * before this is not safe. */ + multi->admin = curl_easy_init(); + if(!multi->admin) { + curlx_free(multi); + return NULL; + } + multi->admin->multi = multi; + multi->admin->state.internal = TRUE; + + /* Now we can use curlx_* things safely */ curlx_pnow(&multi->now); Curl_timeouts_init(&multi->timeouts, &multi->now); + multi_timeouts_init(multi->admin); + Curl_dnscache_init(&multi->dnscache, dnssize); Curl_mntfy_init(multi); Curl_multi_ev_init(multi, ev_hashsize); @@ -269,14 +284,6 @@ struct Curl_multi *Curl_multi_handle(uint32_t xfer_table_size, Curl_uint32_tbl_resize(&multi->xfers, xfer_table_size)) goto error; - multi->admin = curl_easy_init(); - if(!multi->admin) - goto error; - /* Initialize admin handle to operate inside this multi */ - multi->admin->multi = multi; - multi->admin->state.internal = TRUE; - multi_timeouts_init(multi->admin); - #ifdef DEBUGBUILD if(getenv("CURL_DEBUG")) multi->admin->set.verbose = TRUE;