summaryrefslogtreecommitdiffstats
path: root/meta/recipes-support/curl/curl/CVE-2023-27535-pre1.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-support/curl/curl/CVE-2023-27535-pre1.patch')
-rw-r--r--meta/recipes-support/curl/curl/CVE-2023-27535-pre1.patch236
1 files changed, 236 insertions, 0 deletions
diff --git a/meta/recipes-support/curl/curl/CVE-2023-27535-pre1.patch b/meta/recipes-support/curl/curl/CVE-2023-27535-pre1.patch
new file mode 100644
index 0000000000..034b72f7e6
--- /dev/null
+++ b/meta/recipes-support/curl/curl/CVE-2023-27535-pre1.patch
@@ -0,0 +1,236 @@
1From ed5095ed94281989e103c72e032200b83be37878 Mon Sep 17 00:00:00 2001
2From: Daniel Stenberg <daniel@haxx.se>
3Date: Thu, 6 Oct 2022 00:49:10 +0200
4Subject: [PATCH] strcase: add and use Curl_timestrcmp
5
6This is a strcmp() alternative function for comparing "secrets",
7designed to take the same time no matter the content to not leak
8match/non-match info to observers based on how fast it is.
9
10The time this function takes is only a function of the shortest input
11string.
12
13Reported-by: Trail of Bits
14
15Closes #9658
16
17Upstream-Status: Backport from [https://github.com/curl/curl/commit/ed5095ed94281989e103c72e032200b83be37878 & https://github.com/curl/curl/commit/f18af4f874cecab82a9797e8c7541e0990c7a64c]
18Comment: to backport fix for CVE-2023-27535, add function Curl_timestrcmp.
19Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
20---
21 lib/netrc.c | 6 +++---
22 lib/strcase.c | 22 ++++++++++++++++++++++
23 lib/strcase.h | 1 +
24 lib/url.c | 33 +++++++++++++--------------------
25 lib/vauth/digest_sspi.c | 4 ++--
26 lib/vtls/vtls.c | 21 ++++++++++++++++++++-
27 6 files changed, 61 insertions(+), 26 deletions(-)
28
29diff --git a/lib/netrc.c b/lib/netrc.c
30index 9323913..fe3fd1e 100644
31--- a/lib/netrc.c
32+++ b/lib/netrc.c
33@@ -124,9 +124,9 @@ static int parsenetrc(const char *host,
34 /* we are now parsing sub-keywords concerning "our" host */
35 if(state_login) {
36 if(specific_login) {
37- state_our_login = strcasecompare(login, tok);
38+ state_our_login = !Curl_timestrcmp(login, tok);
39 }
40- else if(!login || strcmp(login, tok)) {
41+ else if(!login || Curl_timestrcmp(login, tok)) {
42 if(login_alloc) {
43 free(login);
44 login_alloc = FALSE;
45@@ -142,7 +142,7 @@ static int parsenetrc(const char *host,
46 }
47 else if(state_password) {
48 if((state_our_login || !specific_login)
49- && (!password || strcmp(password, tok))) {
50+ && (!password || Curl_timestrcmp(password, tok))) {
51 if(password_alloc) {
52 free(password);
53 password_alloc = FALSE;
54diff --git a/lib/strcase.c b/lib/strcase.c
55index 70bf21c..ec776b3 100644
56--- a/lib/strcase.c
57+++ b/lib/strcase.c
58@@ -261,6 +261,28 @@ bool Curl_safecmp(char *a, char *b)
59 return !a && !b;
60 }
61
62+/*
63+ * Curl_timestrcmp() returns 0 if the two strings are identical. The time this
64+ * function spends is a function of the shortest string, not of the contents.
65+ */
66+int Curl_timestrcmp(const char *a, const char *b)
67+{
68+ int match = 0;
69+ int i = 0;
70+
71+ if(a && b) {
72+ while(1) {
73+ match |= a[i]^b[i];
74+ if(!a[i] || !b[i])
75+ break;
76+ i++;
77+ }
78+ }
79+ else
80+ return a || b;
81+ return match;
82+}
83+
84 /* --- public functions --- */
85
86 int curl_strequal(const char *first, const char *second)
87diff --git a/lib/strcase.h b/lib/strcase.h
88index 8929a53..8077108 100644
89--- a/lib/strcase.h
90+++ b/lib/strcase.h
91@@ -49,5 +49,6 @@ void Curl_strntoupper(char *dest, const char *src, size_t n);
92 void Curl_strntolower(char *dest, const char *src, size_t n);
93
94 bool Curl_safecmp(char *a, char *b);
95+int Curl_timestrcmp(const char *first, const char *second);
96
97 #endif /* HEADER_CURL_STRCASE_H */
98diff --git a/lib/url.c b/lib/url.c
99index 9f14a7b..dfbde3b 100644
100--- a/lib/url.c
101+++ b/lib/url.c
102@@ -886,19 +886,10 @@ socks_proxy_info_matches(const struct proxy_info* data,
103 /* the user information is case-sensitive
104 or at least it is not defined as case-insensitive
105 see https://tools.ietf.org/html/rfc3986#section-3.2.1 */
106- if((data->user == NULL) != (needle->user == NULL))
107- return FALSE;
108- /* curl_strequal does a case insentive comparison, so do not use it here! */
109- if(data->user &&
110- needle->user &&
111- strcmp(data->user, needle->user) != 0)
112- return FALSE;
113- if((data->passwd == NULL) != (needle->passwd == NULL))
114- return FALSE;
115+
116 /* curl_strequal does a case insentive comparison, so do not use it here! */
117- if(data->passwd &&
118- needle->passwd &&
119- strcmp(data->passwd, needle->passwd) != 0)
120+ if(Curl_timestrcmp(data->user, needle->user) ||
121+ Curl_timestrcmp(data->passwd, needle->passwd))
122 return FALSE;
123 return TRUE;
124 }
125@@ -1257,10 +1248,10 @@ ConnectionExists(struct Curl_easy *data,
126 if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
127 /* This protocol requires credentials per connection,
128 so verify that we're using the same name and password as well */
129- if(strcmp(needle->user, check->user) ||
130- strcmp(needle->passwd, check->passwd) ||
131- !Curl_safecmp(needle->sasl_authzid, check->sasl_authzid) ||
132- !Curl_safecmp(needle->oauth_bearer, check->oauth_bearer)) {
133+ if(Curl_timestrcmp(needle->user, check->user) ||
134+ Curl_timestrcmp(needle->passwd, check->passwd) ||
135+ Curl_timestrcmp(needle->sasl_authzid, check->sasl_authzid) ||
136+ Curl_timestrcmp(needle->oauth_bearer, check->oauth_bearer)) {
137 /* one of them was different */
138 continue;
139 }
140@@ -1326,8 +1317,8 @@ ConnectionExists(struct Curl_easy *data,
141 possible. (Especially we must not reuse the same connection if
142 partway through a handshake!) */
143 if(wantNTLMhttp) {
144- if(strcmp(needle->user, check->user) ||
145- strcmp(needle->passwd, check->passwd)) {
146+ if(Curl_timestrcmp(needle->user, check->user) ||
147+ Curl_timestrcmp(needle->passwd, check->passwd)) {
148
149 /* we prefer a credential match, but this is at least a connection
150 that can be reused and "upgraded" to NTLM */
151@@ -1348,8 +1339,10 @@ ConnectionExists(struct Curl_easy *data,
152 if(!check->http_proxy.user || !check->http_proxy.passwd)
153 continue;
154
155- if(strcmp(needle->http_proxy.user, check->http_proxy.user) ||
156- strcmp(needle->http_proxy.passwd, check->http_proxy.passwd))
157+ if(Curl_timestrcmp(needle->http_proxy.user,
158+ check->http_proxy.user) ||
159+ Curl_timestrcmp(needle->http_proxy.passwd,
160+ check->http_proxy.passwd))
161 continue;
162 }
163 else if(check->proxy_ntlm_state != NTLMSTATE_NONE) {
164diff --git a/lib/vauth/digest_sspi.c b/lib/vauth/digest_sspi.c
165index a109056..3986386 100644
166--- a/lib/vauth/digest_sspi.c
167+++ b/lib/vauth/digest_sspi.c
168@@ -450,8 +450,8 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
169 has changed then delete that context. */
170 if((userp && !digest->user) || (!userp && digest->user) ||
171 (passwdp && !digest->passwd) || (!passwdp && digest->passwd) ||
172- (userp && digest->user && strcmp(userp, digest->user)) ||
173- (passwdp && digest->passwd && strcmp(passwdp, digest->passwd))) {
174+ (userp && digest->user && Curl_timestrcmp(userp, digest->user)) ||
175+ (passwdp && digest->passwd && Curl_timestrcmp(passwdp, digest->passwd))) {
176 if(digest->http_context) {
177 s_pSecFn->DeleteSecurityContext(digest->http_context);
178 Curl_safefree(digest->http_context);
179diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
180index e8cb70f..70a9391 100644
181--- a/lib/vtls/vtls.c
182+++ b/lib/vtls/vtls.c
183@@ -98,9 +98,15 @@ Curl_ssl_config_matches(struct ssl_primary_config* data,
184 Curl_safecmp(data->issuercert, needle->issuercert) &&
185 Curl_safecmp(data->clientcert, needle->clientcert) &&
186 Curl_safecmp(data->random_file, needle->random_file) &&
187- Curl_safecmp(data->egdsocket, needle->egdsocket) &&
188+ Curl_safecmp(data->egdsocket, needle->egdsocket) &&
189+#ifdef USE_TLS_SRP
190+ !Curl_timestrcmp(data->username, needle->username) &&
191+ !Curl_timestrcmp(data->password, needle->password) &&
192+ (data->authtype == needle->authtype) &&
193+#endif
194 Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
195 Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) &&
196+ Curl_safe_strcasecompare(data->CRLfile, needle->CRLfile) &&
197 Curl_safe_strcasecompare(data->pinned_key, needle->pinned_key))
198 return TRUE;
199
200@@ -117,6 +123,9 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
201 dest->verifyhost = source->verifyhost;
202 dest->verifystatus = source->verifystatus;
203 dest->sessionid = source->sessionid;
204+#ifdef USE_TLS_SRP
205+ dest->authtype = source->authtype;
206+#endif
207
208 CLONE_STRING(CApath);
209 CLONE_STRING(CAfile);
210@@ -127,6 +136,11 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
211 CLONE_STRING(cipher_list);
212 CLONE_STRING(cipher_list13);
213 CLONE_STRING(pinned_key);
214+ CLONE_STRING(CRLfile);
215+#ifdef USE_TLS_SRP
216+ CLONE_STRING(username);
217+ CLONE_STRING(password);
218+#endif
219
220 return TRUE;
221 }
222@@ -142,6 +156,11 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc)
223 Curl_safefree(sslc->cipher_list);
224 Curl_safefree(sslc->cipher_list13);
225 Curl_safefree(sslc->pinned_key);
226+ Curl_safefree(sslc->CRLfile);
227+#ifdef USE_TLS_SRP
228+ Curl_safefree(sslc->username);
229+ Curl_safefree(sslc->password);
230+#endif
231 }
232
233 #ifdef USE_SSL
234--
2352.25.1
236