Memory leak of ftp (with proxy reuse)
None
C
curl
Submitted None
Actions:
Reported by
catenacyber
Vulnerability Details
Technical details and impact analysis
## Summary:
[summary of the vulnerability]
There is a memory leak with FTP (see reproducer and stack trace)
I found it via fuzzing with https://github.com/catenacyber/curl-fuzzer/tree/proxy (after fixing a small memory leak in curl)
Just reporting a bit raw, not sure this is not just a small leak that does not go out of security vulnerabilities.
Looks like there are 2 connections `struct connectdata *conn` and the first one of them gets cleaned by `ftp_disconnect` but the second one (with reuse from proxy) is not even if it allocates stuff in `ftp_setup_connection`
I am not even sure the bug is within curl, or if it is in curl_fuzzer
## Affected version
[Which curl/libcurl version are you using to reproduce? On which platform? `curl -V` typically generates good output to include]
curl 8.13.0-DEV (x86_64-apple-darwin23.6.0) libcurl/8.13.0-DEV OpenSSL/1.0.2n zlib/1.2.11 libidn2/2.0.4 libpsl/0.19.1 nghttp2/1.55.1 librtmp/2.3
Release-Date: [unreleased]
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS HSTS HTTP2 HTTPS-proxy IDN IPv6 Largefile libz NTLM PSL SSL threadsafe TLS-SRP UnixSockets
## Steps To Reproduce:
[add details for how we can reproduce the issue]
Run attached fuzz reproducer with the targets built with
```diff
diff --git a/projects/curl/Dockerfile b/projects/curl/Dockerfile
index 1dc106a53..23245c9bf 100644
--- a/projects/curl/Dockerfile
+++ b/projects/curl/Dockerfile
@@ -16,11 +16,11 @@
FROM gcr.io/oss-fuzz-base/base-builder
-RUN git clone --depth 1 https://github.com/curl/curl.git /src/curl
-RUN git clone --depth 1 https://github.com/curl/curl-fuzzer.git /src/curl_fuzzer
+RUN git clone --depth 1 --branch dummy https://github.com/catenacyber/curl.git /src/curl
+RUN git clone --depth 1 --branch proxy https://github.com/catenacyber/curl-fuzzer.git /src/curl_fuzzer
# Use curl-fuzzer's scripts to get latest dependencies.
RUN $SRC/curl_fuzzer/scripts/ossfuzzdeps.sh
WORKDIR $SRC/curl_fuzzer
```
## Supporting Material/References:
[list any additional material (e.g. screenshots, logs, etc.)]
Output of `FUZZ_VERBOSE=1 ./curl_fuzzer_ftp ./minimized-from-5ab60dd6d34f13da35bcebf1f965f8dd6e409e88`
```
TLV: type 1 length 37
Check length of blocked: 43
Remaining length of blocked: 262
TLV: type 2 length 11
Check length of blocked: 60
Remaining length of blocked: 262
TLV: type 11 length 9
Check length of blocked: 75
Remaining length of blocked: 262
TLV: type 12 length 9
Check length of blocked: 90
Remaining length of blocked: 262
TLV: type 13 length 9
Check length of blocked: 105
Remaining length of blocked: 262
TLV: type 14 length 9
Check length of blocked: 120
Remaining length of blocked: 262
TLV: type 15 length 50
Check length of blocked: 176
Remaining length of blocked: 262
TLV: type 16 length 9
Check length of blocked: 191
Remaining length of blocked: 262
TLV: type 17 length 34
Check length of blocked: 231
Remaining length of blocked: 262
TLV: type 18 length 9
Check length of blocked: 246
Remaining length of blocked: 262
TLV: type 72 length 0
Check length of blocked: 252
Remaining length of blocked: 262
TLV: type 21 length 4
Check length of blocked: 262
Remaining length of blocked: 262
FUZZ: Using socket manager 0
FUZZ[0]: Using socket manager 0
FUZZ[0]: Sending initial response
FUZZ: Initial perform; still running? 1
FUZZ: loop still running=1
FUZZ: select rc=1
FUZZ[0]: Received 16 bytes
==>
USER anonymous
<==
FUZZ[0]: Sending next response: 1
FUZZ: send rc=0
FUZZ: loop still running=1
FUZZ: select rc=1
FUZZ[0]: Received 5 bytes
==>
PWD
<==
FUZZ[0]: Sending next response: 2
FUZZ: send rc=0
FUZZ: loop still running=1
FUZZ: select rc=1
FUZZ[0]: Received 15 bytes
==>
CWD test-%ist
<==
FUZZ[0]: Sending next response: 3
FUZZ: send rc=0
FUZZ: loop still running=1
FUZZ: select rc=1
FUZZ[0]: Received 6 bytes
==>
EPSV
<==
FUZZ[0]: Sending next response: 4
FUZZ: send rc=0
FUZZ: loop still running=1
FUZZ: select rc=1
FUZZ[0]: Received 6 bytes
==>
PASV
<==
FUZZ[0]: Sending next response: 5
* Connecting to 127.0.1.127 (127.0.1.127) port 55300
* Trying 127.0.1.127:55300...
* Could not set TCP_NODELAY: Operation not supported
* Connected 2nd connection to 127.0.1.127 port 55300
> TYPE A
* pp_statematch, timeout=185
* pp_statematch, timeout=185
< 200 Sure
> LIST
* pp_statematch, timeout=185
< 150 Success
* Maxdownload = -1
* sendrecv_dl: we are done
* nread <= 0, server closed connection, bailing
* abort upload
* Remembering we are in dir "test-%ist/"
< 226 Everyt???? sent
* Connection #0 to host 127.0.1.127 left intact
* Connecting to hostname: 127.0.1.127
* Re-using existing ftp: connection with host 127.0.0.1
* Remembering we are in dir "test-%ist/*.html"
* Connection #0 to host 127.0.1.127 left intact
=================================================================
==15473==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 17 byte(s) in 1 object(s) allocated from:
#0 0x55ce0ef26f0f in malloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:68:3
#1 0x55ce0ef92cb7 in curl_dbg_malloc /src/curl/lib/memdebug.c:146:9
#2 0x55ce0ef92cb7 in curl_dbg_strdup /src/curl/lib/memdebug.c:200:9
#3 0x55ce0f093870 in ftp_setup_connection /src/curl/lib/ftp.c:4381:21
#4 0x55ce0f005d5d in setup_connection_internals /src/curl/lib/url.c:2024:14
#5 0x55ce0efff415 in create_conn /src/curl/lib/url.c:3522:12
#6 0x55ce0efff415 in Curl_connect /src/curl/lib/url.c:3803:12
#7 0x55ce0efbadff in state_connect /src/curl/lib/multi.c:2149:21
#8 0x55ce0efbadff in multi_runsingle /src/curl/lib/multi.c:2273:12
#9 0x55ce0efb64d2 in curl_multi_perform /src/curl/lib/multi.c:2619:16
#10 0x55ce0ef67b02 in fuzz_handle_transfer(fuzz_data*) /src/curl_fuzzer/curl_fuzzer.cc:424:5
#11 0x55ce0ef669a7 in LLVMFuzzerTestOneInput /src/curl_fuzzer/curl_fuzzer.cc:97:3
```
## Impact
## Summary:
Report Details
Additional information and metadata
State
Closed
Substate
Informative