Read Access violation when using multi interface and ftp wildcard matching #800

Closed
JCMais opened this Issue May 12, 2016 · 3 comments

Projects

None yet

2 participants

@JCMais
JCMais commented May 12, 2016 edited

I had this issue when converting the ftp-wildcard example to my libcurl node.js bindings, which uses the multi interface internally for every request.

I got the following "standalone" (libuv is still required) application to reproduce the issue (it's mostly the multi-uv example with small modifications): https://gist.github.com/JCMais/3f8a570f04f50b38811bc99d47b06ab7

To run it: example.exe ftp://speedtest.tele2.net/*KB.zip

Line of code that is causing the access violation: https://github.com/curl/curl/blob/master/lib/ftplistparser.c#L320

Stack trace:

example.exe!ftp_pl_insert_finfo(connectdata * conn, curl_fileinfo * finfo) Line 320 C
example.exe!Curl_ftp_parselist(char * buffer, unsigned int size, unsigned int nmemb, void * connptr) Line 749 C
example.exe!Curl_client_chop_write(connectdata * conn, int type, char * ptr, unsigned int len) Line 434 C
example.exe!Curl_client_write(connectdata * conn, int type, char * ptr, unsigned int len) Line 511 C
example.exe!readwrite_data(SessionHandle * data, connectdata * conn, SingleRequest * k, int * didwhat, bool * done) Line 753 C
example.exe!Curl_readwrite(connectdata * conn, SessionHandle * data, bool * done) Line 1074 C
example.exe!multi_runsingle(Curl_multi * multi, timeval now, SessionHandle * data) Line 1544 C
example.exe!multi_socket(Curl_multi * multi, bool checkall, unsigned int s, int ev_bitmask, int * running_handles) Line 2291 C
example.exe!curl_multi_socket_action(void * multi_handle, unsigned int s, int ev_bitmask, int * running_handles) Line 2442 C
example.exe!curl_perform(uv_poll_s * req, int status, int events) Line 153 C
example.exe!uv__fast_poll_process_poll_req(uv_loop_s * loop, uv_poll_s * handle, uv_req_s * req) Line 214 C
example.exe!uv_process_poll_req(uv_loop_s * loop, uv_poll_s * handle, uv_req_s * req) Line 622 C
example.exe!uv_process_reqs(uv_loop_s * loop) Line 205 C
example.exe!uv_run(uv_loop_s * loop, uv_run_mode mode) Line 391 C
example.exe!main(int argc, char * * argv) Line 232 C
example.exe!invoke_main() Line 74 C++
example.exe!__scrt_common_main_seh() Line 264 C++
example.exe!__scrt_common_main() Line 309 C++
example.exe!mainCRTStartup() Line 17 C++
kernel32.dll!@BaseThreadInitThunk@12�() Unknown
ntdll.dll!__RtlUserThreadStart() Unknown
ntdll.dll!__RtlUserThreadStart@8�() Unknown

libcurl version:

curl 7.47.1-DEV (i386-pc-win32) libcurl/7.47.1-DEV OpenSSL/1.0.2e zlib/1.2.8 libssh2/1.6.1_DEV
Protocols: dict file ftp ftps gopher http https imap imaps ldap pop3 pop3s rtsp scp sftp smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile SSPI Kerberos SPNEGO NTLM SSL libz

libuv version was the master one at https://github.com/libuv/libuv

Had this issue on Windows, I could not test on Unix but the issue is probably there too.

@bagder bagder added crash FTP labels May 12, 2016
@JCMais
JCMais commented May 12, 2016

I just ran the code under debian 8 and had the same issue:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7bb0739 in ftp_pl_insert_finfo.isra () from /home/jc/local/lib/libcurl.so.4
(gdb) where
#0  0x00007ffff7bb0739 in ftp_pl_insert_finfo.isra () from /home/jc/local/lib/libcurl.so.4
#1  0x00007ffff7bb0bf5 in Curl_ftp_parselist () from /home/jc/local/lib/libcurl.so.4
#2  0x00007ffff7b99a8a in Curl_client_chop_write () from /home/jc/local/lib/libcurl.so.4
#3  0x00007ffff7badf4a in Curl_readwrite () from /home/jc/local/lib/libcurl.so.4
#4  0x00007ffff7bb63fc in multi_runsingle () from /home/jc/local/lib/libcurl.so.4
#5  0x00007ffff7bb74ae in multi_socket () from /home/jc/local/lib/libcurl.so.4
#6  0x00007ffff7bb7677 in curl_multi_socket_action () from /home/jc/local/lib/libcurl.so.4
#7  0x000000000040141a in curl_perform (req=0x6255c0, status=0, events=1) at example.c:113
#8  0x00007ffff797f198 in uv__io_poll (loop=loop@entry=0x7ffff7b89900 <default_loop_struct>, timeout=-1)
    at src/unix/linux-core.c:380
#9  0x00007ffff7971568 in uv_run (loop=0x7ffff7b89900 <default_loop_struct>, mode=UV_RUN_DEFAULT)
    at src/unix/core.c:354
#10 0x0000000000401683 in main (argc=0, argv=0x7fffffffe598) at example.c:192

curl -V

curl 7.49.0-DEV (x86_64-unknown-linux-gnu) libcurl/7.49.0-DEV
Protocols: dict file ftp gopher http imap pop3 rtsp smtp telnet tftp
Features: IPv6 Largefile UnixSockets
@bagder bagder self-assigned this May 14, 2016
@bagder
Member
bagder commented May 14, 2016

I can reproduce...

@bagder bagder added a commit that closed this issue May 14, 2016
@bagder bagder ftp wildcard: segfault due to init only in multi_perform
The proper FTP wildcard init is now more properly done in Curl_pretransfer()
and the corresponding cleanup in Curl_close().

The previous place of init/cleanup code made the internal pointer to be NULL
when this feature was used with the multi_socket() API, as it was made within
the curl_multi_perform() function.

Reported-by: Jonathan Cardoso Machado
Fixes #800
cba9621
@bagder bagder closed this in cba9621 May 14, 2016
@bagder
Member
bagder commented May 14, 2016

Your test program works fine for me after this fix. Thanks a lot for your clear and accurate report!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment