Description
## Summary:
There is a double-free in libcurl with rustls.
The root cause is reported and it is fixed in https://github.com/curl/curl/pull/19425, while I did not try to evaluate the actual triggering at that time.
No AI was used to find the issue or generate the report.
## Affected version
It was introduced via commit https://github.com/curl/curl/commit/088f0e6a5b8d934073a0e089ebecd14ca75120c4 on Mar 25, 2025.
It affected the official version from v8.13.0 to v8.17.0.
## Steps To Reproduce:
1. Installation:
(1) Install rustls-ffi via https://github.com/rustls/rustls-ffi/releases/download/v0.15.0/librustls_0.15.0_amd64.deb.zip.
(2) Build curl-8_17_0 from source. (my configure is: "./configure --enable-debug --enable-static --disable-shared --with-rustls")
2. Compile the basic PoC program via "gcc -o test_rustls_fail test.c -I./include ./lib/.libs/libcurl.a -lnghttp2 -lpsl -lrustls -lpthread -lz -fsanitize=address -g" (The source of PoC program is attached). The basic target is to trigger NoServerCertVerifier of rustls_client_config_builder_build() at https://github.com/rustls/rustls-ffi/blob/0b5f053fe5200e262ed70c100cc5486ce76d9d8a/librustls/src/client.rs#L505.
In cr_init_backend, https://github.com/curl/curl/blob/master/lib/vtls/rustls.c#L1046-L1067 is for setting the verifier. Once `!conn_config->verifypeer`, `ssl_config->native_ca_store` and `(ca_info_blob || ssl_cafile)` are not satisfied, then the verifier will not be inited.
3. Run the PoC program. The output/sanitizer info will show the double-free problem.
Note:
I did not fully try other unsuccessful possibilities of rustls_client_config_builder_build(). The PoC is just a real triggering case to show the existence of double-free.
Based on my personal analysis, it is mainly affect the libcurl and it is hard to reproduce it in a controllable manner for curl tool.
However, there is still a risk of curl crashing in the oom scenario.
For example, the API `rustls_client_config_builder_dangerous_set_certificate_verifier` returns OK yet the verifier may not be successfully set due to oom at https://github.com/rustls/rustls-ffi/blob/0b5f053fe5200e262ed70c100cc5486ce76d9d8a/librustls/src/client.rs#L218.
Maybe we can also further prevent it earlier just like below:
```c
else if(ca_info_blob || ssl_cafile) {
result = init_config_builder_verifier(data,
config_builder,
conn_config,
ca_info_blob,
ssl_cafile);
if(result != CURLE_OK) {
rustls_client_config_builder_free(config_builder);
return result;
}
}
+ else {
+ rustls_client_config_builder_free(config_builder);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
```
## Supporting Material/References:
The source of PoC program.
* Please see the attached file `test.c`.
There is a double-free in libcurl with rustls.
The root cause is reported and it is fixed in https://github.com/curl/curl/pull/19425, while I did not try to evaluate the actual triggering at that time.
No AI was used to find the issue or generate the report.
## Affected version
It was introduced via commit https://github.com/curl/curl/commit/088f0e6a5b8d934073a0e089ebecd14ca75120c4 on Mar 25, 2025.
It affected the official version from v8.13.0 to v8.17.0.
## Steps To Reproduce:
1. Installation:
(1) Install rustls-ffi via https://github.com/rustls/rustls-ffi/releases/download/v0.15.0/librustls_0.15.0_amd64.deb.zip.
(2) Build curl-8_17_0 from source. (my configure is: "./configure --enable-debug --enable-static --disable-shared --with-rustls")
2. Compile the basic PoC program via "gcc -o test_rustls_fail test.c -I./include ./lib/.libs/libcurl.a -lnghttp2 -lpsl -lrustls -lpthread -lz -fsanitize=address -g" (The source of PoC program is attached). The basic target is to trigger NoServerCertVerifier of rustls_client_config_builder_build() at https://github.com/rustls/rustls-ffi/blob/0b5f053fe5200e262ed70c100cc5486ce76d9d8a/librustls/src/client.rs#L505.
In cr_init_backend, https://github.com/curl/curl/blob/master/lib/vtls/rustls.c#L1046-L1067 is for setting the verifier. Once `!conn_config->verifypeer`, `ssl_config->native_ca_store` and `(ca_info_blob || ssl_cafile)` are not satisfied, then the verifier will not be inited.
3. Run the PoC program. The output/sanitizer info will show the double-free problem.
Note:
I did not fully try other unsuccessful possibilities of rustls_client_config_builder_build(). The PoC is just a real triggering case to show the existence of double-free.
Based on my personal analysis, it is mainly affect the libcurl and it is hard to reproduce it in a controllable manner for curl tool.
However, there is still a risk of curl crashing in the oom scenario.
For example, the API `rustls_client_config_builder_dangerous_set_certificate_verifier` returns OK yet the verifier may not be successfully set due to oom at https://github.com/rustls/rustls-ffi/blob/0b5f053fe5200e262ed70c100cc5486ce76d9d8a/librustls/src/client.rs#L218.
Maybe we can also further prevent it earlier just like below:
```c
else if(ca_info_blob || ssl_cafile) {
result = init_config_builder_verifier(data,
config_builder,
conn_config,
ca_info_blob,
ssl_cafile);
if(result != CURLE_OK) {
rustls_client_config_builder_free(config_builder);
return result;
}
}
+ else {
+ rustls_client_config_builder_free(config_builder);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
```
## Supporting Material/References:
The source of PoC program.
* Please see the attached file `test.c`.
Basic Information
ID
H1:3427670
Published
Nov 16, 2025 at 07:32
Modified
Nov 16, 2025 at 22:40