From 121c54016869622729131fe36d111f52cb1fac89 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Sun, 7 Dec 2025 20:03:38 +0100 Subject: [PATCH] sspi: fix memory leaks on error paths in `Curl_create_sspi_identity()` Detected by Windows torture test 1072 (with `-shallow=20/13`), test 579 (with `-shallow=18/14/13`), and test 1286 (with `-shallow=15`). ``` ** MEMORY FAILURE Leak detected: memory still allocated: 20 bytes At 1a1e8136328, there is 18 bytes. allocated by D:/a/curl/curl/lib/curl_sspi.c:133 At 1a1e8139368, there is 2 bytes. allocated by D:/a/curl/curl/lib/curl_sspi.c:143 1072: torture FAILED: function number 207 in test. invoke with "-t207" to repeat this single case. Warning: http2 server unexpectedly alive ``` Ref: https://github.com/curl/curl/actions/runs/20008523913/job/57374427439?pr=19865 Also simplify the code a little. Cherry-picked from #19865 Closes #19866 --- lib/curl_sspi.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/curl_sspi.c b/lib/curl_sspi.c index 712fab2e9e..35a9bc33e6 100644 --- a/lib/curl_sspi.c +++ b/lib/curl_sspi.c @@ -135,33 +135,34 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, curlx_free(useranddomain.tchar_ptr); return CURLE_OUT_OF_MEMORY; } - identity->User = dup_user.tbyte_ptr; - identity->UserLength = curlx_uztoul(_tcslen(dup_user.tchar_ptr)); - dup_user.tchar_ptr = NULL; /* Setup the identity's domain and length */ dup_domain.tchar_ptr = curlx_malloc(sizeof(TCHAR) * (domlen + 1)); if(!dup_domain.tchar_ptr) { + curlx_free(dup_user.tchar_ptr); curlx_free(useranddomain.tchar_ptr); return CURLE_OUT_OF_MEMORY; } if(_tcsncpy_s(dup_domain.tchar_ptr, domlen + 1, domain.tchar_ptr, domlen)) { + curlx_free(dup_user.tchar_ptr); curlx_free(dup_domain.tchar_ptr); curlx_free(useranddomain.tchar_ptr); return CURLE_OUT_OF_MEMORY; } - identity->Domain = dup_domain.tbyte_ptr; - identity->DomainLength = curlx_uztoul(domlen); - dup_domain.tchar_ptr = NULL; curlx_free(useranddomain.tchar_ptr); /* Setup the identity's password and length */ passwd.tchar_ptr = curlx_convert_UTF8_to_tchar(passwdp); - if(!passwd.tchar_ptr) + if(!passwd.tchar_ptr) { + curlx_free(dup_user.tchar_ptr); + curlx_free(dup_domain.tchar_ptr); return CURLE_OUT_OF_MEMORY; + } dup_passwd.tchar_ptr = curlx_tcsdup(passwd.tchar_ptr); if(!dup_passwd.tchar_ptr) { + curlx_free(dup_user.tchar_ptr); + curlx_free(dup_domain.tchar_ptr); curlx_free(passwd.tchar_ptr); return CURLE_OUT_OF_MEMORY; } @@ -171,6 +172,13 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, curlx_free(passwd.tchar_ptr); + identity->User = dup_user.tbyte_ptr; + identity->UserLength = curlx_uztoul(_tcslen(dup_user.tchar_ptr)); + dup_user.tchar_ptr = NULL; + identity->Domain = dup_domain.tbyte_ptr; + identity->DomainLength = curlx_uztoul(domlen); + dup_domain.tchar_ptr = NULL; + /* Setup the identity's flags */ identity->Flags = (unsigned long) #ifdef UNICODE -- 2.47.3