I did this
When a multi-threaded application uses curl_share with CURL_LOCK_DATA_CONNECT, url_match_destination dereferences the refcounted conn->origin under the cpool lock, while url_conn_reuse_adjust swaps and frees the old origin outside the lock via Curl_peer_link. The in-lock read then dereferences freed memory (use-after-free) → SIGSEGV.
Thread 240 (LWP 1451):
#0 0x0000007f7eeb0e78 in ?? () from /data1/huangchangwei6/nfs/CoreDump/coredump/coredump/lib/lib/libc.so.6
#1 0x0000007f7eeb6ebc in pthread_mutex_lock () from /data1/huangchangwei6/nfs/CoreDump/coredump/coredump/lib/lib/libc.so.6
#2 0x0000007f7f7adeb4 in Curl_share_lock (data=0x7f3400ecb0, type=CURL_LOCK_DATA_CONNECT, accesstype=CURL_LOCK_ACCESS_SINGLE) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/curl_share.c:381
#3 0x0000007f7f792768 in Curl_cpool_do_locked (data=0x7f3400ecb0, conn=0x7f6c04ce40, cb=0x7f7f8078d8 <multi_done_locked>, cbdata=0x7eb337c9f0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/conncache.c:834
#4 0x0000007f7f808014 in multi_done (data=0x7f3400ecb0, status=CURLE_OK, premature=false) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:766
#5 0x0000007f7f80c940 in multistate_done (data=0x7f3400ecb0, presult=0x7eb337ca80) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2694
#6 0x0000007f7f80ce24 in multi_runsingle (multi=0x7f340409f0, data=0x7f3400ecb0, sigpipe_ctx=0x7eb337cb08) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2842
#7 0x0000007f7f80d0fc in multi_perform (multi=0x7f340409f0, running_handles=0x7eb337cc10) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2915
#8 0x0000007f7f80d378 in curl_multi_perform (m=0x7f340409f0, running_handles=0x7eb337cc10) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2976
#9 0x0000007f7f7bed78 in easy_transfer (multi=0x7f340409f0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:694
#10 0x0000007f7f7bf054 in easy_perform (data=0x7f3400ecb0, events=false) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:802
#11 0x0000007f7f7bf0d4 in curl_easy_perform (curl=0x7f3400ecb0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:820
Thread 186 (LWP 1370):
#0 0x0000007f7eeb0e78 in ?? () from /data1/huangchangwei6/nfs/CoreDump/coredump/coredump/lib/lib/libc.so.6
#1 0x0000007f7eeb6ebc in pthread_mutex_lock () from /data1/huangchangwei6/nfs/CoreDump/coredump/coredump/lib/lib/libc.so.6
#2 0x0000007f7f7adeb4 in Curl_share_lock (data=0x7f6c056000, type=CURL_LOCK_DATA_CONNECT, accesstype=CURL_LOCK_ACCESS_SINGLE) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/curl_share.c:381
#3 0x0000007f7f792768 in Curl_cpool_do_locked (data=0x7f6c056000, conn=0x7f6c04ff80, cb=0x7f7f8078d8 <multi_done_locked>, cbdata=0x7ec1e7fff0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/conncache.c:834
#4 0x0000007f7f808014 in multi_done (data=0x7f6c056000, status=CURLE_OK, premature=false) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:766
#5 0x0000007f7f80c940 in multistate_done (data=0x7f6c056000, presult=0x7ec1e80080) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2694
#6 0x0000007f7f80ce24 in multi_runsingle (multi=0x7f6c0820b0, data=0x7f6c056000, sigpipe_ctx=0x7ec1e80108) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2842
#7 0x0000007f7f80d0fc in multi_perform (multi=0x7f6c0820b0, running_handles=0x7ec1e80210) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2915
#8 0x0000007f7f80d378 in curl_multi_perform (m=0x7f6c0820b0, running_handles=0x7ec1e80210) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2976
#9 0x0000007f7f7bed78 in easy_transfer (multi=0x7f6c0820b0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:694
#10 0x0000007f7f7bf054 in easy_perform (data=0x7f6c056000, events=false) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:802
Thread 1 (LWP 1300):
#0 url_match_destination (conn=0x7f6c04ff80, m=0x7ec57d6948) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/url.c:977
#1 0x0000007f7f857998 in url_match_conn (conn=0x7f6c04ff80, userdata=0x7ec57d6948) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/url.c:1133
#2 0x0000007f7f791afc in Curl_cpool_find (data=0x7f04027bd0, destination=0x7f6c01f930 "10.187.68.143:80", conn_cb=0x7f7f857938 <url_match_conn>, done_cb=0x7f7f857be0 <url_match_result>, userdata=0x7ec57d6948) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/conncache.c:621
#3 0x0000007f7f857e3c in url_attach_existing (data=0x7f04027bd0, needle=0x7f0400da30, waitpipe=0x7ec57d6992) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/url.c:1260
#4 0x0000007f7f859ec4 in url_find_or_create_conn (data=0x7f04027bd0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/url.c:2392
#5 0x0000007f7f85a3a4 in Curl_connect (data=0x7f04027bd0, pconnected=0x7ec57d6a2f) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/url.c:2541
#6 0x0000007f7f80ba08 in multistate_connect (multi=0x7f0402a6b0, data=0x7f04027bd0, resultp=0x7ec57d6a80) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2331
#7 0x0000007f7f80cd00 in multi_runsingle (multi=0x7f0402a6b0, data=0x7f04027bd0, sigpipe_ctx=0x7ec57d6b08) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2796
#8 0x0000007f7f80d0fc in multi_perform (multi=0x7f0402a6b0, running_handles=0x7ec57d6c10) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2915
#9 0x0000007f7f80d378 in curl_multi_perform (m=0x7f0402a6b0, running_handles=0x7ec57d6c10) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2976
#10 0x0000007f7f7bed78 in easy_transfer (multi=0x7f0402a6b0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:694
#11 0x0000007f7f7bf054 in easy_perform (data=0x7f04027bd0, events=false) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:802
#12 0x0000007f7f7bf0d4 in curl_easy_perform (curl=0x7f04027bd0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:820
I expected the following
Concurrent curl_easy_perform calls from multiple threads sharing a connection pool (the documented use case for CURL_LOCK_DATA_CONNECT + lockfunc/unlockfunc) should be safe. The shared pool's lockfunc serializes access to the connection cache, so connection reuse across threads should never corrupt memory or crash
curl/libcurl version
curl 8.21.0
operating system
aarch64 Linux
I did this
When a multi-threaded application uses curl_share with CURL_LOCK_DATA_CONNECT, url_match_destination dereferences the refcounted conn->origin under the cpool lock, while url_conn_reuse_adjust swaps and frees the old origin outside the lock via Curl_peer_link. The in-lock read then dereferences freed memory (use-after-free) → SIGSEGV.
Thread 240 (LWP 1451):
#0 0x0000007f7eeb0e78 in ?? () from /data1/huangchangwei6/nfs/CoreDump/coredump/coredump/lib/lib/libc.so.6
#1 0x0000007f7eeb6ebc in pthread_mutex_lock () from /data1/huangchangwei6/nfs/CoreDump/coredump/coredump/lib/lib/libc.so.6
#2 0x0000007f7f7adeb4 in Curl_share_lock (data=0x7f3400ecb0, type=CURL_LOCK_DATA_CONNECT, accesstype=CURL_LOCK_ACCESS_SINGLE) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/curl_share.c:381
#3 0x0000007f7f792768 in Curl_cpool_do_locked (data=0x7f3400ecb0, conn=0x7f6c04ce40, cb=0x7f7f8078d8 <multi_done_locked>, cbdata=0x7eb337c9f0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/conncache.c:834
#4 0x0000007f7f808014 in multi_done (data=0x7f3400ecb0, status=CURLE_OK, premature=false) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:766
#5 0x0000007f7f80c940 in multistate_done (data=0x7f3400ecb0, presult=0x7eb337ca80) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2694
#6 0x0000007f7f80ce24 in multi_runsingle (multi=0x7f340409f0, data=0x7f3400ecb0, sigpipe_ctx=0x7eb337cb08) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2842
#7 0x0000007f7f80d0fc in multi_perform (multi=0x7f340409f0, running_handles=0x7eb337cc10) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2915
#8 0x0000007f7f80d378 in curl_multi_perform (m=0x7f340409f0, running_handles=0x7eb337cc10) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2976
#9 0x0000007f7f7bed78 in easy_transfer (multi=0x7f340409f0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:694
#10 0x0000007f7f7bf054 in easy_perform (data=0x7f3400ecb0, events=false) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:802
#11 0x0000007f7f7bf0d4 in curl_easy_perform (curl=0x7f3400ecb0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:820
Thread 186 (LWP 1370):
#0 0x0000007f7eeb0e78 in ?? () from /data1/huangchangwei6/nfs/CoreDump/coredump/coredump/lib/lib/libc.so.6
#1 0x0000007f7eeb6ebc in pthread_mutex_lock () from /data1/huangchangwei6/nfs/CoreDump/coredump/coredump/lib/lib/libc.so.6
#2 0x0000007f7f7adeb4 in Curl_share_lock (data=0x7f6c056000, type=CURL_LOCK_DATA_CONNECT, accesstype=CURL_LOCK_ACCESS_SINGLE) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/curl_share.c:381
#3 0x0000007f7f792768 in Curl_cpool_do_locked (data=0x7f6c056000, conn=0x7f6c04ff80, cb=0x7f7f8078d8 <multi_done_locked>, cbdata=0x7ec1e7fff0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/conncache.c:834
#4 0x0000007f7f808014 in multi_done (data=0x7f6c056000, status=CURLE_OK, premature=false) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:766
#5 0x0000007f7f80c940 in multistate_done (data=0x7f6c056000, presult=0x7ec1e80080) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2694
#6 0x0000007f7f80ce24 in multi_runsingle (multi=0x7f6c0820b0, data=0x7f6c056000, sigpipe_ctx=0x7ec1e80108) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2842
#7 0x0000007f7f80d0fc in multi_perform (multi=0x7f6c0820b0, running_handles=0x7ec1e80210) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2915
#8 0x0000007f7f80d378 in curl_multi_perform (m=0x7f6c0820b0, running_handles=0x7ec1e80210) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2976
#9 0x0000007f7f7bed78 in easy_transfer (multi=0x7f6c0820b0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:694
#10 0x0000007f7f7bf054 in easy_perform (data=0x7f6c056000, events=false) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:802
Thread 1 (LWP 1300):
#0 url_match_destination (conn=0x7f6c04ff80, m=0x7ec57d6948) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/url.c:977
#1 0x0000007f7f857998 in url_match_conn (conn=0x7f6c04ff80, userdata=0x7ec57d6948) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/url.c:1133
#2 0x0000007f7f791afc in Curl_cpool_find (data=0x7f04027bd0, destination=0x7f6c01f930 "10.187.68.143:80", conn_cb=0x7f7f857938 <url_match_conn>, done_cb=0x7f7f857be0 <url_match_result>, userdata=0x7ec57d6948) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/conncache.c:621
#3 0x0000007f7f857e3c in url_attach_existing (data=0x7f04027bd0, needle=0x7f0400da30, waitpipe=0x7ec57d6992) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/url.c:1260
#4 0x0000007f7f859ec4 in url_find_or_create_conn (data=0x7f04027bd0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/url.c:2392
#5 0x0000007f7f85a3a4 in Curl_connect (data=0x7f04027bd0, pconnected=0x7ec57d6a2f) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/url.c:2541
#6 0x0000007f7f80ba08 in multistate_connect (multi=0x7f0402a6b0, data=0x7f04027bd0, resultp=0x7ec57d6a80) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2331
#7 0x0000007f7f80cd00 in multi_runsingle (multi=0x7f0402a6b0, data=0x7f04027bd0, sigpipe_ctx=0x7ec57d6b08) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2796
#8 0x0000007f7f80d0fc in multi_perform (multi=0x7f0402a6b0, running_handles=0x7ec57d6c10) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2915
#9 0x0000007f7f80d378 in curl_multi_perform (m=0x7f0402a6b0, running_handles=0x7ec57d6c10) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/multi.c:2976
#10 0x0000007f7f7bed78 in easy_transfer (multi=0x7f0402a6b0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:694
#11 0x0000007f7f7bf054 in easy_perform (data=0x7f04027bd0, events=false) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:802
#12 0x0000007f7f7bf0d4 in curl_easy_perform (curl=0x7f04027bd0) at /usr/local/docker_workspace/src/openSrc/curl-8.21.0/lib/easy.c:820
I expected the following
Concurrent
curl_easy_performcalls from multiple threads sharing a connection pool (the documented use case forCURL_LOCK_DATA_CONNECT+lockfunc/unlockfunc) should be safe. The shared pool'slockfuncserializes access to the connection cache, so connection reuse across threads should never corrupt memory or crashcurl/libcurl version
curl 8.21.0
operating system
aarch64 Linux