Skip to content

Commit

Permalink
urldata: move hstslist from 'set' to 'state'
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bagder committed Nov 13, 2023
1 parent 7cb0322 commit 289b486
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 11 deletions.
2 changes: 1 addition & 1 deletion lib/hsts.c
Expand Up @@ -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);

Expand Down
12 changes: 6 additions & 6 deletions lib/setopt.c
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion lib/url.c
Expand Up @@ -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);
Expand Down
5 changes: 2 additions & 3 deletions lib/urldata.h
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 289b486

Please sign in to comment.