Use-After-Free in SMB connection reuse (req->path dangling pointer after needle destruction)

Disclosed: 2026-04-29 07:16:24 By nadsec42 To curl
High
Vulnerability Details
## Summary A heap-use-after-free occurs in `smb_send_open()` at `lib/smb.c` when curl processes two SMB URLs targeting the same host. The function `smb_parse_url_path()` sets `req->path` as a non-owning pointer into `smbc->share` (connection-owned memory). During connection reuse, the needle connection is freed via `Curl_conn_free()` → `smb_conn_dtor()`, which frees `smbc->share`, but `req->path` (on the easy handle) still references the freed buffer. The subsequent `strlen(req->path)` in `smb_send_open()` reads freed heap memory. ## Affected Version curl 8.19.0-DEV (master branch, built March 8 2026) Platform: Ubuntu 22.04 on x86_64 (WSL2) Built with: gcc, OpenSSL, --enable-smb, -fsanitize=address ## Steps To Reproduce 1. Clone and build curl from master with ASAN and SMB enabled: ``` git clone https://github.com/curl/curl.git && cd curl autoreconf -fi ./configure --with-openssl --enable-smb --without-libpsl make CFLAGS="-fsanitize=address -g -O0 -fno-omit-frame-pointer" LDFLAGS="-fsanitize=address" -j$(nproc) ``` 2. Start the attached fake SMB server (fake_smb_server.py) in one terminal: ``` python3 fake_smb_server.py 5445 ``` 3. In another terminal, run curl with two SMB URLs to the same host: ``` ASAN_OPTIONS=detect_leaks=0 LD_LIBRARY_PATH=./lib/.libs \ ./src/.libs/curl -u guest:guest \ "smb://127.0.0.1:5445/share1/file1" -o /dev/null \ "smb://127.0.0.1:5445/share2/file2" -o /dev/null ``` 4. ASAN reports heap-use-after-free in smb_send_open. ## Root Cause In `smb_parse_url_path()` (lib/smb.c ~line 398-435): - `smbc->share = strdup(path)` allocates "share2/file2" (13 bytes) - The `/` is replaced with `\0`, splitting it into "share2\0file2\0" - `req->path = slash` points 7 bytes into `smbc->share` When the second URL reuses the pooled connection from URL #1: - `url_find_or_create_conn()` finds a match and frees the needle connection - `Curl_conn_free()` → `smb_conn_dtor()` → `free(smbc->share)` - `req->path` now dangles into freed heap Then `smb_request_state()` → `smb_send_open()`: ```c const size_t byte_count = strlen(req->path) + 1; // UAF read ``` ASAN confirms: "0x502000002a57 is located 7 bytes inside of 13-byte region, freed by smb_conn_dtor, previously allocated by smb_parse_url_path via strdup" ## ASAN Output ``` ==519095==ERROR: AddressSanitizer: heap-use-after-free on address 0x502000002a57 at pc 0x7967a543daa7 bp 0x7fffdbfd8b00 sp 0x7fffdbfd82a8 READ of size 1 at 0x502000002a57 thread T0 #0 0x7967a543daa6 in __interceptor_strlen #1 0x7967a51a4326 in smb_send_open (libcurl.so.4) #2 0x7967a51a75fe in smb_request_state (libcurl.so.4) #3 0x7967a5158fbf in protocol_doing (libcurl.so.4) #4 0x7967a515d395 in multi_runsingle (libcurl.so.4) #5 0x7967a515e569 in multi_perform (libcurl.so.4) #6 0x7967a515ebe0 in curl_multi_perform (libcurl.so.4) #7 0x7967a50bc841 in easy_transfer (libcurl.so.4) #8 0x7967a50bcf0a in easy_perform (libcurl.so.4) #9 0x7967a50bcffe in curl_easy_perform (libcurl.so.4) #10 0x5d0efa2f6ea2 in serial_transfers (curl) #11 0x5d0efa2f80b2 in run_all_transfers (curl) #12 0x5d0efa2f8cd6 in operate (curl) #13 0x5d0efa2ea7b4 in main (curl) freed by thread T0 here: #0 __interceptor_free #1 smb_conn_dtor (libcurl.so.4) #2 hash_elem_clear_ptr (libcurl.so.4) #3 hash_elem_destroy (libcurl.so.4) #4 Curl_hash_clean (libcurl.so.4) #5 Curl_hash_destroy (libcurl.so.4) #6 Curl_conn_free (libcurl.so.4) #7 url_find_or_create_conn (libcurl.so.4) previously allocated by thread T0 here: #0 __interceptor_strdup #1 smb_parse_url_path (libcurl.so.4) #2 smb_setup_connection (libcurl.so.4) #3 setup_connection_internals (libcurl.so.4) #4 url_create_needle (libcurl.so.4) #5 url_find_or_create_conn (libcurl.so.4) SUMMARY: AddressSanitizer: heap-use-after-free in __interceptor_strlen 0x502000002a57 is located 7 bytes inside of 13-byte region [0x502000002a50,0x502000002a5d) ``` ## Impact Heap-use-after-free (CWE-416) triggered by a simple two-URL curl command line. Requires no authentication to a real SMB server - the UAF occurs client-side before any server response to the second request. This results in a guaranteed crash (DoS). If the freed 13-byte heap region is reallocated with attacker-influenced data before the read, it could potentially lead to information disclosure or further memory corruption.
Actions
View on HackerOne
Report Stats
  • Report ID: 3591956
  • State: Closed
  • Substate: duplicate
Share this report