From 289b486ffaa4dc654aafeb31e000a6576f8794aa Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 13 Nov 2023 12:37:50 +0100 Subject: [PATCH] urldata: move hstslist from 'set' to 'state' To make it work properly with curl_easy_duphandle(). This, because duphandle duplicates the entire 'UserDefined' struct by plain copy while 'hstslist' is a linked curl_list of file names. This would lead to a double-free when the second of the two involved easy handles were closed. Closes #12315 --- lib/hsts.c | 2 +- lib/setopt.c | 12 ++++++------ lib/url.c | 2 +- lib/urldata.h | 5 ++--- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/hsts.c b/lib/hsts.c index 7e71bb29a6..9314be294b 100644 --- a/lib/hsts.c +++ b/lib/hsts.c @@ -572,7 +572,7 @@ CURLcode Curl_hsts_loadcb(struct Curl_easy *data, struct hsts *h) void Curl_hsts_loadfiles(struct Curl_easy *data) { - struct curl_slist *l = data->set.hstslist; + struct curl_slist *l = data->state.hstslist; if(l) { Curl_share_lock(data, CURL_LOCK_DATA_HSTS, CURL_LOCK_ACCESS_SINGLE); diff --git a/lib/setopt.c b/lib/setopt.c index c3ff34fac5..9bebcaa8fb 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -3066,18 +3066,18 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* this needs to build a list of file names to read from, so that it can read them later, as we might get a shared HSTS handle to load them into */ - h = curl_slist_append(data->set.hstslist, argptr); + h = curl_slist_append(data->state.hstslist, argptr); if(!h) { - curl_slist_free_all(data->set.hstslist); - data->set.hstslist = NULL; + curl_slist_free_all(data->state.hstslist); + data->state.hstslist = NULL; return CURLE_OUT_OF_MEMORY; } - data->set.hstslist = h; /* store the list for later use */ + data->state.hstslist = h; /* store the list for later use */ } else { /* clear the list of HSTS files */ - curl_slist_free_all(data->set.hstslist); - data->set.hstslist = NULL; + curl_slist_free_all(data->state.hstslist); + data->state.hstslist = NULL; if(!data->share || !data->share->hsts) /* throw away the HSTS cache unless shared */ Curl_hsts_cleanup(&data->hsts); diff --git a/lib/url.c b/lib/url.c index f0d04e8857..cf8da4aedf 100644 --- a/lib/url.c +++ b/lib/url.c @@ -412,7 +412,7 @@ CURLcode Curl_close(struct Curl_easy **datap) #ifndef CURL_DISABLE_HSTS if(!data->share || !data->share->hsts) Curl_hsts_cleanup(&data->hsts); - curl_slist_free_all(data->set.hstslist); /* clean up list */ + curl_slist_free_all(data->state.hstslist); /* clean up list */ #endif #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_DIGEST_AUTH) Curl_http_auth_cleanup_digest(data); diff --git a/lib/urldata.h b/lib/urldata.h index 1828fc4cd4..30d6a43943 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -1344,7 +1344,8 @@ struct UrlState { curl_off_t recent_conn_id; /* The most recent connection used, might no * longer exist */ struct dynbuf headerb; /* buffer to store headers in */ - + struct curl_slist *hstslist; /* list of HSTS files set by + curl_easy_setopt(HSTS) calls */ char *buffer; /* download buffer */ char *ulbuf; /* allocated upload buffer or NULL */ curl_off_t current_speed; /* the ProgressShow() function sets this, @@ -1698,8 +1699,6 @@ struct UserDefined { curl_easy_setopt(COOKIEFILE) calls */ #endif #ifndef CURL_DISABLE_HSTS - struct curl_slist *hstslist; /* list of HSTS files set by - curl_easy_setopt(HSTS) calls */ curl_hstsread_callback hsts_read; void *hsts_read_userp; curl_hstswrite_callback hsts_write; -- 2.47.3