Use-After-Free in SMB connection reuse (req->path dangling pointer after needle destruction)
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 HackerOneReport Stats
- Report ID: 3591956
- State: Closed
- Substate: duplicate