diff options
author | Daniel Stenberg <daniel@haxx.se> | 2019-12-09 11:53:54 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2019-12-09 15:30:09 +0100 |
commit | ee263de7a378e701f15e58879f36fdcfe8742006 (patch) | |
tree | 5fdf1aafe027c7e659cfaa989f429b5159645a79 /lib/conncache.h | |
parent | 9e891ff54de34d0e4c9aec502eb53e5b64a6dd1f (diff) | |
download | curl-ee263de7a378e701f15e58879f36fdcfe8742006.tar.gz |
conncache: fix multi-thread use of shared connection cache
It could accidentally let the connection get used by more than one
thread, leading to double-free and more.
Reported-by: Christopher Reid
Fixes #4544
Closes #4557
Diffstat (limited to 'lib/conncache.h')
-rw-r--r-- | lib/conncache.h | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/lib/conncache.h b/lib/conncache.h index 58f902409..5fe80b4c8 100644 --- a/lib/conncache.h +++ b/lib/conncache.h @@ -42,6 +42,27 @@ struct conncache { #define BUNDLE_UNKNOWN 0 /* initial value */ #define BUNDLE_MULTIPLEX 2 +#ifdef CURLDEBUG +/* the debug versions of these macros make extra certain that the lock is + never doubly locked or unlocked */ +#define CONN_LOCK(x) if((x)->share) { \ + Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE); \ + DEBUGASSERT(!(x)->state.conncache_lock); \ + (x)->state.conncache_lock = TRUE; \ + } + +#define CONN_UNLOCK(x) if((x)->share) { \ + DEBUGASSERT((x)->state.conncache_lock); \ + (x)->state.conncache_lock = FALSE; \ + Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT); \ + } +#else +#define CONN_LOCK(x) if((x)->share) \ + Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE) +#define CONN_UNLOCK(x) if((x)->share) \ + Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT) +#endif + struct connectbundle { int multiuse; /* supports multi-use */ size_t num_connections; /* Number of connections in the bundle */ @@ -61,7 +82,8 @@ void Curl_conncache_unlock(struct Curl_easy *data); size_t Curl_conncache_size(struct Curl_easy *data); size_t Curl_conncache_bundle_size(struct connectdata *conn); -bool Curl_conncache_return_conn(struct connectdata *conn); +bool Curl_conncache_return_conn(struct Curl_easy *data, + struct connectdata *conn); CURLcode Curl_conncache_add_conn(struct conncache *connc, struct connectdata *conn) WARN_UNUSED_RESULT; void Curl_conncache_remove_conn(struct Curl_easy *data, |