Skip to content

SIGSEGV (use-after-free on conn->origin) in url_match_destination with shared connection pool #386

Description

@Nod9876543

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions