summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorYogita Urade <yogita.urade@windriver.com>2025-07-08 14:27:28 +0530
committerSteve Sakoman <steve@sakoman.com>2025-07-14 08:37:40 -0700
commit580a1571c4bc7341bd19b067b9e5a8bc4194b627 (patch)
tree133939d536f65e3700735d30d6a7efb5f572d2ab /meta
parentdef97edcef31f0bfdea674de70684bcbd1b2e134 (diff)
downloadpoky-580a1571c4bc7341bd19b067b9e5a8bc4194b627.tar.gz
curl: fix CVE-2024-11053
When asked to both use a `.netrc` file for credentials and to follow HTTP redirects, curl could leak the password used for the first host to the followed-to host under certain circumstances. This flaw only manifests itself if the netrc file has an entry that matches the redirect target hostname but the entry either omits just the password or omits both login and password. References: https://nvd.nist.gov/vuln/detail/CVE-2024-11053 https://git.launchpad.net/ubuntu/+source/curl/diff/debian/patches/CVE-2024-11053-pre1.patch?id=2126676d86041cabd7b1aa302fc1fdf47989df95 https://git.launchpad.net/ubuntu/+source/curl/diff/debian/patches/CVE-2024-11053.patch?id=2126676d86041cabd7b1aa302fc1fdf47989df95 Upstream patch: https://github.com/curl/curl/commit/9bee39bfed2c413b4cc4eb306a57ac92a1854907 https://github.com/curl/curl/commit/e9b9bbac22c26cf67316fa8e6c6b9e831af31949 (From OE-Core rev: 87823ff05a4f90b42c138902639a59231fa17def) Signed-off-by: Yogita Urade <yogita.urade@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
Diffstat (limited to 'meta')
-rw-r--r--meta/recipes-support/curl/curl/CVE-2024-11053-0001.patch340
-rw-r--r--meta/recipes-support/curl/curl/CVE-2024-11053-0002.patch746
-rw-r--r--meta/recipes-support/curl/curl_7.82.0.bb2
3 files changed, 1088 insertions, 0 deletions
diff --git a/meta/recipes-support/curl/curl/CVE-2024-11053-0001.patch b/meta/recipes-support/curl/curl/CVE-2024-11053-0001.patch
new file mode 100644
index 0000000000..86ca27a694
--- /dev/null
+++ b/meta/recipes-support/curl/curl/CVE-2024-11053-0001.patch
@@ -0,0 +1,340 @@
1From 9bee39bfed2c413b4cc4eb306a57ac92a1854907 Mon Sep 17 00:00:00 2001
2From: Daniel Stenberg <daniel@haxx.se>
3Date: Sat, 12 Oct 2024 23:54:39 +0200
4Subject: [PATCH] url: use same credentials on redirect
5
6Previously it could lose the username and only use the password.
7
8Added test 998 and 999 to verify.
9
10Reported-by: Tobias Bora
11Fixes #15262
12Closes #15282
13
14CVE: CVE-2024-11053
15Upstream-Status: Backport [https://github.com/curl/curl/commit/9bee39bfed2c413b4cc4eb306a57ac92a1854907]
16
17Changes:
18- Refresh patch context.
19- Small change in the Makefile to add a new test.
20
21Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
22---
23 lib/transfer.c | 3 ++
24 lib/url.c | 18 ++++----
25 lib/urldata.h | 8 ++++
26 tests/data/Makefile.inc | 2 +-
27 tests/data/test998 | 92 +++++++++++++++++++++++++++++++++++++++++
28 tests/data/test999 | 81 ++++++++++++++++++++++++++++++++++++
29 6 files changed, 194 insertions(+), 10 deletions(-)
30 create mode 100644 tests/data/test998
31 create mode 100644 tests/data/test999
32
33diff --git a/lib/transfer.c b/lib/transfer.c
34index d567c4b..cd7365b 100644
35--- a/lib/transfer.c
36+++ b/lib/transfer.c
37@@ -1479,6 +1479,9 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
38 return CURLE_OUT_OF_MEMORY;
39 }
40
41+ if(data->set.str[STRING_USERNAME] ||
42+ data->set.str[STRING_PASSWORD])
43+ data->state.creds_from = CREDS_OPTION;
44 if(!result)
45 result = Curl_setstropt(&data->state.aptr.user,
46 data->set.str[STRING_USERNAME]);
47diff --git a/lib/url.c b/lib/url.c
48index 9406cca..99d1082 100644
49--- a/lib/url.c
50+++ b/lib/url.c
51@@ -2098,10 +2098,10 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
52 return result;
53
54 /*
55- * User name and password set with their own options override the
56- * credentials possibly set in the URL.
57+ * username and password set with their own options override the credentials
58+ * possibly set in the URL, but netrc does not.
59 */
60- if(!data->state.aptr.passwd) {
61+ if(!data->state.aptr.passwd || (data->state.creds_from != CREDS_OPTION)) {
62 uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0);
63 if(!uc) {
64 char *decoded;
65@@ -2112,6 +2112,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
66 return result;
67 conn->passwd = decoded;
68 result = Curl_setstropt(&data->state.aptr.passwd, decoded);
69+ data->state.creds_from = CREDS_URL;
70 if(result)
71 return result;
72 }
73@@ -2119,7 +2120,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
74 return Curl_uc_to_curlcode(uc);
75 }
76
77- if(!data->state.aptr.user) {
78+ if(!data->state.aptr.user || (data->state.creds_from != CREDS_OPTION)) {
79 /* we don't use the URL API's URL decoder option here since it rejects
80 control codes and we want to allow them for some schemes in the user
81 and password fields */
82@@ -2133,13 +2134,10 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
83 return result;
84 conn->user = decoded;
85 result = Curl_setstropt(&data->state.aptr.user, decoded);
86+ data->state.creds_from = CREDS_URL;
87 }
88 else if(uc != CURLUE_NO_USER)
89 return Curl_uc_to_curlcode(uc);
90- else if(data->state.aptr.passwd) {
91- /* no user was set but a password, set a blank user */
92- result = Curl_setstropt(&data->state.aptr.user, "");
93- }
94 if(result)
95 return result;
96 }
97@@ -3032,7 +3030,8 @@ static CURLcode override_login(struct Curl_easy *data,
98 if(result)
99 return result;
100 }
101- if(data->state.aptr.user) {
102+ if(data->state.aptr.user &&
103+ (data->state.creds_from != CREDS_NETRC)) {
104 uc = curl_url_set(data->state.uh, CURLUPART_USER, data->state.aptr.user,
105 CURLU_URLENCODE);
106 if(uc)
107@@ -3048,6 +3047,7 @@ static CURLcode override_login(struct Curl_easy *data,
108 CURLcode result = Curl_setstropt(&data->state.aptr.passwd, *passwdp);
109 if(result)
110 return result;
111+ data->state.creds_from = CREDS_NETRC;
112 }
113 if(data->state.aptr.passwd) {
114 uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD,
115diff --git a/lib/urldata.h b/lib/urldata.h
116index e78a7e8..d252e73 100644
117--- a/lib/urldata.h
118+++ b/lib/urldata.h
119@@ -1324,6 +1324,11 @@ struct urlpieces {
120 char *query;
121 };
122
123+#define CREDS_NONE 0
124+#define CREDS_URL 1 /* from URL */
125+#define CREDS_OPTION 2 /* set with a CURLOPT_ */
126+#define CREDS_NETRC 3 /* found in netrc */
127+
128 struct UrlState {
129 /* Points to the connection cache */
130 struct conncache *conn_cache;
131@@ -1454,6 +1459,9 @@ struct UrlState {
132 char *proxypasswd;
133 } aptr;
134
135+ unsigned int creds_from:2; /* where is the server credentials originating
136+ from, see the CREDS_* defines above */
137+
138 #ifdef CURLDEBUG
139 BIT(conncache_lock);
140 #endif
141diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
142index 5415f37..00cdfb8 100644
143--- a/tests/data/Makefile.inc
144+++ b/tests/data/Makefile.inc
145@@ -123,7 +123,7 @@ test954 test955 test956 test957 test958 test959 test960 test961 test962 \
146 test963 test964 test965 test966 test967 test968 test969 test970 test971 \
147 test972 \
148 \
149-test980 test981 test982 test983 test984 test985 test986 \
150+test980 test981 test982 test983 test984 test985 test986 test998 test999 \
151 \
152 test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \
153 test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \
154diff --git a/tests/data/test998 b/tests/data/test998
155new file mode 100644
156index 0000000..6dcd95f
157--- /dev/null
158+++ b/tests/data/test998
159@@ -0,0 +1,92 @@
160+<testcase>
161+<info>
162+<keywords>
163+HTTP
164+--location-trusted
165+</keywords>
166+</info>
167+
168+#
169+# Server-side
170+<reply>
171+<data>
172+HTTP/1.1 301 redirect
173+Date: Tue, 09 Nov 2010 14:49:00 GMT
174+Server: test-server/fake
175+Content-Length: 0
176+Connection: close
177+Content-Type: text/html
178+Location: http://somewhere.else.example/a/path/%TESTNUMBER0002
179+
180+</data>
181+<data2>
182+HTTP/1.1 200 OK
183+Date: Tue, 09 Nov 2010 14:49:00 GMT
184+Content-Length: 6
185+Content-Type: text/html
186+Funny-head: yesyes
187+
188+-foo-
189+</data2>
190+
191+<datacheck>
192+HTTP/1.1 301 redirect
193+Date: Tue, 09 Nov 2010 14:49:00 GMT
194+Server: test-server/fake
195+Content-Length: 0
196+Connection: close
197+Content-Type: text/html
198+Location: http://somewhere.else.example/a/path/%TESTNUMBER0002
199+
200+HTTP/1.1 200 OK
201+Date: Tue, 09 Nov 2010 14:49:00 GMT
202+Content-Length: 6
203+Content-Type: text/html
204+Funny-head: yesyes
205+
206+-foo-
207+</datacheck>
208+
209+</reply>
210+
211+#
212+# Client-side
213+<client>
214+<features>
215+proxy
216+</features>
217+<server>
218+http
219+</server>
220+<name>
221+HTTP with auth in URL redirected to another host
222+</name>
223+<command>
224+-x %HOSTIP:%HTTPPORT http://alberto:einstein@somwhere.example/%TESTNUMBER --location-trusted
225+</command>
226+</client>
227+
228+#
229+# Verify data after the test has been "shot"
230+<verify>
231+<strip>
232+QUIT
233+</strip>
234+<protocol>
235+GET http://somwhere.example/998 HTTP/1.1
236+Host: somwhere.example
237+Authorization: Basic YWxiZXJ0bzplaW5zdGVpbg==
238+User-Agent: curl/%VERSION
239+Accept: */*
240+Proxy-Connection: Keep-Alive
241+
242+GET http://somewhere.else.example/a/path/9980002 HTTP/1.1
243+Host: somewhere.else.example
244+Authorization: Basic YWxiZXJ0bzplaW5zdGVpbg==
245+User-Agent: curl/%VERSION
246+Accept: */*
247+Proxy-Connection: Keep-Alive
248+
249+</protocol>
250+</verify>
251+</testcase>
252diff --git a/tests/data/test999 b/tests/data/test999
253new file mode 100644
254index 0000000..e805cde
255--- /dev/null
256+++ b/tests/data/test999
257@@ -0,0 +1,81 @@
258+<testcase>
259+<info>
260+<keywords>
261+HTTP
262+--location-trusted
263+</keywords>
264+</info>
265+
266+#
267+# Server-side
268+<reply>
269+<data nocheck="yes">
270+HTTP/1.1 200 OK
271+Date: Tue, 09 Nov 2010 14:49:00 GMT
272+Content-Length: 6
273+Content-Type: text/html
274+Funny-head: yesyes
275+
276+-foo-
277+</data>
278+
279+<datacheck>
280+HTTP/1.1 301 redirect
281+Date: Tue, 09 Nov 2010 14:49:00 GMT
282+Server: test-server/fake
283+Content-Length: 0
284+Connection: close
285+Content-Type: text/html
286+Location: http://somewhere.else.example/a/path/%TESTNUMBER0002
287+
288+HTTP/1.1 200 OK
289+Date: Tue, 09 Nov 2010 14:49:00 GMT
290+Content-Length: 6
291+Content-Type: text/html
292+Funny-head: yesyes
293+
294+-foo-
295+</datacheck>
296+
297+</reply>
298+
299+#
300+# Client-side
301+<client>
302+<features>
303+proxy
304+</features>
305+<server>
306+http
307+</server>
308+<name>
309+HTTP with auth in first URL but not second
310+</name>
311+<command>
312+-x %HOSTIP:%HTTPPORT http://alberto:einstein@somwhere.example/%TESTNUMBER http://somewhere.else.example/%TESTNUMBER
313+</command>
314+</client>
315+
316+#
317+# Verify data after the test has been "shot"
318+<verify>
319+<strip>
320+QUIT
321+</strip>
322+<protocol>
323+GET http://somwhere.example/%TESTNUMBER HTTP/1.1
324+Host: somwhere.example
325+Authorization: Basic YWxiZXJ0bzplaW5zdGVpbg==
326+User-Agent: curl/%VERSION
327+Accept: */*
328+Proxy-Connection: Keep-Alive
329+
330+GET http://somewhere.else.example/%TESTNUMBER HTTP/1.1
331+Host: somewhere.else.example
332+User-Agent: curl/%VERSION
333+Accept: */*
334+Proxy-Connection: Keep-Alive
335+
336+</protocol>
337+</verify>
338+</testcase>
339--
3402.40.0
diff --git a/meta/recipes-support/curl/curl/CVE-2024-11053-0002.patch b/meta/recipes-support/curl/curl/CVE-2024-11053-0002.patch
new file mode 100644
index 0000000000..5db0499987
--- /dev/null
+++ b/meta/recipes-support/curl/curl/CVE-2024-11053-0002.patch
@@ -0,0 +1,746 @@
1From e9b9bbac22c26cf67316fa8e6c6b9e831af31949 Mon Sep 17 00:00:00 2001
2From: Daniel Stenberg <daniel@haxx.se>
3Date: Fri, 15 Nov 2024 11:06:36 +0100
4Subject: [PATCH] netrc: address several netrc parser flaws
5
6- make sure that a match that returns a username also returns a
7 password, that should be blank if no password is found
8
9- fix handling of multiple logins for same host where the password/login
10 order might be reversed.
11
12- reject credentials provided in the .netrc if they contain ASCII control
13 codes - if the used protocol does not support such (like HTTP and WS do)
14
15Reported-by: Harry Sintonen
16
17Add test 478, 479 and 480 to verify. Updated unit 1304.
18
19Closes #15586
20
21Changes:
22- Refresh patch context.
23- Adjust `%LOGDIR/` to 'log/' due to its absence in code.
24- Replaces the previous usage of the state_login, state_password, and
25 state_our_login variables with the found_state enum, which includes the
26 values NONE, LOGIN, and PASSWORD. As a result, all conditionals and memory
27 management logic associated with these variables were updated.
28- Updates to use password and login instead of s_password and s_login,
29 which do not exist in the current version. This change preserves the
30 same logic while adapting the code to the current structure.
31- test478 is disabled as this version of curl does not support searching
32 for a specific login in the netrc file.
33 (see https://github.com/curl/curl/issues/8241)
34- test480 is disabled as this version of curl does not support quoted or
35 escaped strings in the netrc file.
36 (see https://github.com/curl/curl/issues/8908)
37- Small change in the Makefile to add a new test
38
39CVE: CVE-2024-11053
40Upstream-Status: Backport [https://github.com/curl/curl/commit/e9b9bbac22c26cf67316fa8e6c6b9e831af31949]
41
42Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
43---
44 lib/netrc.c | 121 ++++++++++++++++++++++------------------
45 lib/url.c | 53 ++++++++++++------
46 tests/data/DISABLED | 3 +
47 tests/data/Makefile.inc | 2 +-
48 tests/data/test478 | 73 ++++++++++++++++++++++++
49 tests/data/test479 | 107 +++++++++++++++++++++++++++++++++++
50 tests/data/test480 | 38 +++++++++++++
51 tests/unit/unit1304.c | 81 +++++++--------------------
52 8 files changed, 348 insertions(+), 130 deletions(-)
53 create mode 100644 tests/data/test478
54 create mode 100644 tests/data/test479
55 create mode 100644 tests/data/test480
56
57diff --git a/lib/netrc.c b/lib/netrc.c
58index b771b60..23080b3 100644
59--- a/lib/netrc.c
60+++ b/lib/netrc.c
61@@ -46,6 +46,15 @@ enum host_lookup_state {
62 MACDEF
63 };
64
65+enum found_state {
66+ NONE,
67+ LOGIN,
68+ PASSWORD
69+};
70+
71+#define FOUND_LOGIN 1
72+#define FOUND_PASSWORD 2
73+
74 #define NETRC_FILE_MISSING 1
75 #define NETRC_FAILED -1
76 #define NETRC_SUCCESS 0
77@@ -54,7 +63,7 @@ enum host_lookup_state {
78 * Returns zero on success.
79 */
80 static int parsenetrc(const char *host,
81- char **loginp,
82+ char **loginp, /* might point to a username */
83 char **passwordp,
84 bool *login_changed,
85 bool *password_changed,
86@@ -63,16 +72,14 @@ static int parsenetrc(const char *host,
87 FILE *file;
88 int retcode = NETRC_FILE_MISSING;
89 char *login = *loginp;
90- char *password = *passwordp;
91- bool specific_login = (login && *login != 0);
92- bool login_alloc = FALSE;
93- bool password_alloc = FALSE;
94+ char *password = NULL;
95+ bool specific_login = login; /* points to something */
96 enum host_lookup_state state = NOTHING;
97
98- char state_login = 0; /* Found a login keyword */
99- char state_password = 0; /* Found a password keyword */
100- int state_our_login = FALSE; /* With specific_login, found *our* login
101- name */
102+ enum found_state keyword = NONE;
103+ unsigned char found = 0; /* login + password found bits, as they can come in
104+ any order */
105+ bool our_login = FALSE; /* found our login name */
106
107 DEBUGASSERT(netrcfile);
108
109@@ -95,11 +102,7 @@ static int parsenetrc(const char *host,
110 if(tok && *tok == '#')
111 /* treat an initial hash as a comment line */
112 continue;
113- while(tok) {
114- if((login && *login) && (password && *password)) {
115- done = TRUE;
116- break;
117- }
118+ while(tok && !done) {
119
120 switch(state) {
121 case NOTHING:
122@@ -115,6 +118,12 @@ static int parsenetrc(const char *host,
123 after this we need to search for 'login' and
124 'password'. */
125 state = HOSTFOUND;
126+ keyword = NONE;
127+ found = 0;
128+ our_login = FALSE;
129+ Curl_safefree(password);
130+ if(!specific_login)
131+ Curl_safefree(login);
132 }
133 else if(strcasecompare("default", tok)) {
134 state = HOSTVALID;
135@@ -138,48 +147,55 @@ static int parsenetrc(const char *host,
136 break;
137 case HOSTVALID:
138 /* we are now parsing sub-keywords concerning "our" host */
139- if(state_login) {
140+ if(keyword == LOGIN) {
141 if(specific_login) {
142- state_our_login = !Curl_timestrcmp(login, tok);
143+ our_login = !Curl_timestrcmp(login, tok);
144 }
145- else if(!login || Curl_timestrcmp(login, tok)) {
146- if(login_alloc) {
147- free(login);
148- login_alloc = FALSE;
149- }
150+ else {
151+ our_login = TRUE;
152+ free(login);
153 login = strdup(tok);
154 if(!login) {
155 retcode = NETRC_FAILED; /* allocation failed */
156 goto out;
157 }
158- login_alloc = TRUE;
159 }
160- state_login = 0;
161+ found |= FOUND_LOGIN;
162+ keyword = NONE;
163 }
164- else if(state_password) {
165- if((state_our_login || !specific_login)
166- && (!password || Curl_timestrcmp(password, tok))) {
167- if(password_alloc) {
168- free(password);
169- password_alloc = FALSE;
170- }
171- password = strdup(tok);
172- if(!password) {
173- retcode = NETRC_FAILED; /* allocation failed */
174- goto out;
175- }
176- password_alloc = TRUE;
177+ else if(keyword == PASSWORD) {
178+ free(password);
179+ password = strdup(tok);
180+ if(!password) {
181+ retcode = NETRC_FAILED; /* allocation failed */
182+ goto out;
183 }
184- state_password = 0;
185+ found |= FOUND_PASSWORD;
186+ keyword = NONE;
187 }
188 else if(strcasecompare("login", tok))
189- state_login = 1;
190+ keyword = LOGIN;
191 else if(strcasecompare("password", tok))
192- state_password = 1;
193+ keyword = PASSWORD;
194 else if(strcasecompare("machine", tok)) {
195- /* ok, there's machine here go => */
196+ /* a new machine here */
197 state = HOSTFOUND;
198- state_our_login = FALSE;
199+ keyword = NONE;
200+ found = 0;
201+ Curl_safefree(password);
202+ if(!specific_login)
203+ Curl_safefree(login);
204+ }
205+ else if(strcasecompare("default", tok)) {
206+ state = HOSTVALID;
207+ retcode = NETRC_SUCCESS; /* we did find our host */
208+ Curl_safefree(password);
209+ if(!specific_login)
210+ Curl_safefree(login);
211+ }
212+ if((found == (FOUND_PASSWORD|FOUND_LOGIN)) && our_login) {
213+ done = TRUE;
214+ break;
215 }
216 break;
217 } /* switch (state) */
218@@ -189,28 +205,27 @@ static int parsenetrc(const char *host,
219 } /* while fgets() */
220
221 out:
222+ if(!retcode && !password && our_login) {
223+ /* success without a password, set a blank one */
224+ password = strdup("");
225+ if(!password)
226+ retcode = 1; /* out of memory */
227+ }
228 if(!retcode) {
229 /* success */
230 *login_changed = FALSE;
231 *password_changed = FALSE;
232- if(login_alloc) {
233- if(*loginp)
234- free(*loginp);
235+ if(!specific_login) {
236 *loginp = login;
237 *login_changed = TRUE;
238 }
239- if(password_alloc) {
240- if(*passwordp)
241- free(*passwordp);
242- *passwordp = password;
243- *password_changed = TRUE;
244- }
245+ *passwordp = password;
246+ *password_changed = TRUE;
247 }
248 else {
249- if(login_alloc)
250+ if(!specific_login)
251 free(login);
252- if(password_alloc)
253- free(password);
254+ free(password);
255 }
256 fclose(file);
257 }
258diff --git a/lib/url.c b/lib/url.c
259index 99d1082..48835c9 100644
260--- a/lib/url.c
261+++ b/lib/url.c
262@@ -2954,6 +2954,17 @@ static CURLcode parse_remote_port(struct Curl_easy *data,
263 return CURLE_OK;
264 }
265
266+static bool str_has_ctrl(const char *input)
267+{
268+ const unsigned char *str = (const unsigned char *)input;
269+ while(*str) {
270+ if(*str < 0x20)
271+ return TRUE;
272+ str++;
273+ }
274+ return FALSE;
275+}
276+
277 /*
278 * Override the login details from the URL with that in the CURLOPT_USERPWD
279 * option or a .netrc file, if applicable.
280@@ -2995,22 +3006,32 @@ static CURLcode override_login(struct Curl_easy *data,
281 url_provided = TRUE;
282 }
283
284- ret = Curl_parsenetrc(conn->host.name,
285- userp, passwdp,
286- &netrc_user_changed, &netrc_passwd_changed,
287- data->set.str[STRING_NETRC_FILE]);
288- if(ret > 0) {
289- infof(data, "Couldn't find host %s in the %s file; using defaults",
290- conn->host.name, data->set.str[STRING_NETRC_FILE]);
291- }
292- else if(ret < 0) {
293- return CURLE_OUT_OF_MEMORY;
294- }
295- else {
296- /* set bits.netrc TRUE to remember that we got the name from a .netrc
297- file, so that it is safe to use even if we followed a Location: to a
298- different host or similar. */
299- conn->bits.netrc = TRUE;
300+ if(!*passwdp) {
301+ ret = Curl_parsenetrc(conn->host.name,
302+ userp, passwdp,
303+ &netrc_user_changed, &netrc_passwd_changed,
304+ data->set.str[STRING_NETRC_FILE]);
305+ if(ret > 0) {
306+ infof(data, "Couldn't find host %s in the %s file; using defaults",
307+ conn->host.name, data->set.str[STRING_NETRC_FILE]);
308+ }
309+ else if(ret < 0) {
310+ return CURLE_OUT_OF_MEMORY;
311+ }
312+ else {
313+ if(!(conn->handler->flags&PROTOPT_USERPWDCTRL)) {
314+ /* if the protocol can't handle control codes in credentials, make
315+ sure there are none */
316+ if(str_has_ctrl(*userp) || str_has_ctrl(*passwdp)) {
317+ failf(data, "control code detected in .netrc credentials");
318+ return CURLE_READ_ERROR;
319+ }
320+ }
321+ /* set bits.netrc TRUE to remember that we got the name from a .netrc
322+ file, so that it is safe to use even if we followed a Location: to a
323+ different host or similar. */
324+ conn->bits.netrc = TRUE;
325+ }
326 }
327 if(url_provided) {
328 Curl_safefree(conn->user);
329diff --git a/tests/data/DISABLED b/tests/data/DISABLED
330index 7187ec3..4434c41 100644
331--- a/tests/data/DISABLED
332+++ b/tests/data/DISABLED
333@@ -85,3 +85,6 @@
334 %if wolfssl
335 313
336 %endif
337+# 478 and 480 are backported and do not work with this version of curl
338+478
339+480
340diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
341index 00cdfb8..ad41a5e 100644
342--- a/tests/data/Makefile.inc
343+++ b/tests/data/Makefile.inc
344@@ -73,7 +73,7 @@ test418 \
345 \
346 test430 test431 test432 test433 test434 test435 test436 \
347 \
348-test446 \
349+test446 test478 test479 test480 \
350 test490 test491 test492 test493 test494 \
351 \
352 test500 test501 test502 test503 test504 test505 test506 test507 test508 \
353diff --git a/tests/data/test478 b/tests/data/test478
354new file mode 100644
355index 0000000..c356ef5
356--- /dev/null
357+++ b/tests/data/test478
358@@ -0,0 +1,73 @@
359+<testcase>
360+<info>
361+<keywords>
362+netrc
363+HTTP
364+</keywords>
365+</info>
366+#
367+# Server-side
368+<reply>
369+<data crlf="yes">
370+HTTP/1.1 200 OK
371+Date: Tue, 09 Nov 2010 14:49:00 GMT
372+Server: test-server/fake
373+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
374+ETag: "21025-dc7-39462498"
375+Accept-Ranges: bytes
376+Content-Length: 6
377+Connection: close
378+Content-Type: text/html
379+Funny-head: yesyes
380+
381+-foo-
382+</data>
383+</reply>
384+
385+#
386+# Client-side
387+<client>
388+<server>
389+http
390+</server>
391+<features>
392+proxy
393+</features>
394+<name>
395+.netrc with multiple accounts for same host
396+</name>
397+<command>
398+--netrc --netrc-file log/netrc%TESTNUMBER -x http://%HOSTIP:%HTTPPORT/ http://debbie@github.com/
399+</command>
400+<file name="log/netrc%TESTNUMBER" >
401+
402+machine github.com
403+password weird
404+password firstone
405+login daniel
406+
407+machine github.com
408+
409+machine github.com
410+login debbie
411+
412+machine github.com
413+password weird
414+password "second\r"
415+login debbie
416+
417+</file>
418+</client>
419+
420+<verify>
421+<protocol>
422+GET http://github.com/ HTTP/1.1
423+Host: github.com
424+Authorization: Basic %b64[debbie:second%0D]b64%
425+User-Agent: curl/%VERSION
426+Accept: */*
427+Proxy-Connection: Keep-Alive
428+
429+</protocol>
430+</verify>
431+</testcase>
432diff --git a/tests/data/test479 b/tests/data/test479
433new file mode 100644
434index 0000000..8d67fdf
435--- /dev/null
436+++ b/tests/data/test479
437@@ -0,0 +1,107 @@
438+<testcase>
439+<info>
440+<keywords>
441+netrc
442+HTTP
443+</keywords>
444+</info>
445+#
446+# Server-side
447+<reply>
448+<data crlf="yes">
449+HTTP/1.1 301 Follow this you fool
450+Date: Tue, 09 Nov 2010 14:49:00 GMT
451+Server: test-server/fake
452+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
453+ETag: "21025-dc7-39462498"
454+Accept-Ranges: bytes
455+Content-Length: 6
456+Connection: close
457+Location: http://b.com/%TESTNUMBER0002
458+
459+-foo-
460+</data>
461+
462+<data2 crlf="yes">
463+HTTP/1.1 200 OK
464+Date: Tue, 09 Nov 2010 14:49:00 GMT
465+Server: test-server/fake
466+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
467+ETag: "21025-dc7-39462498"
468+Accept-Ranges: bytes
469+Content-Length: 7
470+Connection: close
471+
472+target
473+</data2>
474+
475+<datacheck crlf="yes">
476+HTTP/1.1 301 Follow this you fool
477+Date: Tue, 09 Nov 2010 14:49:00 GMT
478+Server: test-server/fake
479+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
480+ETag: "21025-dc7-39462498"
481+Accept-Ranges: bytes
482+Content-Length: 6
483+Connection: close
484+Location: http://b.com/%TESTNUMBER0002
485+
486+HTTP/1.1 200 OK
487+Date: Tue, 09 Nov 2010 14:49:00 GMT
488+Server: test-server/fake
489+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
490+ETag: "21025-dc7-39462498"
491+Accept-Ranges: bytes
492+Content-Length: 7
493+Connection: close
494+
495+target
496+</datacheck>
497+</reply>
498+
499+#
500+# Client-side
501+<client>
502+<server>
503+http
504+</server>
505+<features>
506+proxy
507+</features>
508+<name>
509+.netrc with redirect and default without password
510+</name>
511+<command>
512+--netrc --netrc-file log/netrc%TESTNUMBER -L -x http://%HOSTIP:%HTTPPORT/ http://a.com/
513+</command>
514+<file name="log/netrc%TESTNUMBER" >
515+
516+machine a.com
517+ login alice
518+ password alicespassword
519+
520+default
521+ login bob
522+
523+</file>
524+</client>
525+
526+<verify>
527+<protocol>
528+GET http://a.com/ HTTP/1.1
529+Host: a.com
530+Authorization: Basic %b64[alice:alicespassword]b64%
531+User-Agent: curl/%VERSION
532+Accept: */*
533+Proxy-Connection: Keep-Alive
534+
535+GET http://b.com/%TESTNUMBER0002 HTTP/1.1
536+Host: b.com
537+Authorization: Basic %b64[bob:]b64%
538+User-Agent: curl/%VERSION
539+Accept: */*
540+Proxy-Connection: Keep-Alive
541+
542+</protocol>
543+</verify>
544+</testcase>
545diff --git a/tests/data/test480 b/tests/data/test480
546new file mode 100644
547index 0000000..f097f81
548--- /dev/null
549+++ b/tests/data/test480
550@@ -0,0 +1,38 @@
551+<testcase>
552+<info>
553+<keywords>
554+netrc
555+pop3
556+</keywords>
557+</info>
558+#
559+# Server-side
560+<reply>
561+
562+</reply>
563+
564+#
565+# Client-side
566+<client>
567+<server>
568+pop3
569+</server>
570+<name>
571+Reject .netrc with credentials using CRLF for POP3
572+</name>
573+<command>
574+--netrc --netrc-file log/netrc%TESTNUMBER pop3://%HOSTIP:%POP3PORT/%TESTNUMBER
575+</command>
576+<file name="log/netrc%TESTNUMBER" >
577+machine %HOSTIP
578+ login alice
579+ password "password\r\ncommand"
580+</file>
581+</client>
582+
583+<verify>
584+<errorcode>
585+26
586+</errorcode>
587+</verify>
588+</testcase>
589diff --git a/tests/unit/unit1304.c b/tests/unit/unit1304.c
590index a6dc64d..d2dba14 100644
591--- a/tests/unit/unit1304.c
592+++ b/tests/unit/unit1304.c
593@@ -29,13 +29,8 @@ static char filename[64];
594
595 static CURLcode unit_setup(void)
596 {
597- password = strdup("");
598- login = strdup("");
599- if(!password || !login) {
600- Curl_safefree(password);
601- Curl_safefree(login);
602- return CURLE_OUT_OF_MEMORY;
603- }
604+ password = NULL;
605+ login = NULL;
606 return CURLE_OK;
607 }
608
609@@ -59,86 +54,52 @@ UNITTEST_START
610 result = Curl_parsenetrc("test.example.com", &login, &password,
611 &login_changed, &password_changed, filename);
612 fail_unless(result == 1, "Host not found should return 1");
613- abort_unless(password != NULL, "returned NULL!");
614- fail_unless(password[0] == 0, "password should not have been changed");
615- abort_unless(login != NULL, "returned NULL!");
616- fail_unless(login[0] == 0, "login should not have been changed");
617+ abort_unless(password == NULL, "password did not return NULL!");
618+ abort_unless(login == NULL, "user did not return NULL!");
619
620 /*
621 * Test a non existent login in our netrc file.
622 */
623- free(login);
624- login = strdup("me");
625- abort_unless(login != NULL, "returned NULL!");
626+ login = (char *)"me";
627 result = Curl_parsenetrc("example.com", &login, &password,
628 &login_changed, &password_changed, filename);
629 fail_unless(result == 0, "Host should have been found");
630- abort_unless(password != NULL, "returned NULL!");
631- fail_unless(password[0] == 0, "password should not have been changed");
632- fail_unless(!password_changed, "password should not have been changed");
633- abort_unless(login != NULL, "returned NULL!");
634- fail_unless(strncmp(login, "me", 2) == 0,
635- "login should not have been changed");
636- fail_unless(!login_changed, "login should not have been changed");
637+ abort_unless(password == NULL, "password is not NULL!");
638
639 /*
640 * Test a non existent login and host in our netrc file.
641 */
642- free(login);
643- login = strdup("me");
644- abort_unless(login != NULL, "returned NULL!");
645+ login = (char *)"me";
646 result = Curl_parsenetrc("test.example.com", &login, &password,
647 &login_changed, &password_changed, filename);
648 fail_unless(result == 1, "Host not found should return 1");
649- abort_unless(password != NULL, "returned NULL!");
650- fail_unless(password[0] == 0, "password should not have been changed");
651- abort_unless(login != NULL, "returned NULL!");
652- fail_unless(strncmp(login, "me", 2) == 0,
653- "login should not have been changed");
654+ abort_unless(password == NULL, "password is not NULL!");
655
656 /*
657 * Test a non existent login (substring of an existing one) in our
658 * netrc file.
659 */
660- free(login);
661- login = strdup("admi");
662- abort_unless(login != NULL, "returned NULL!");
663+ login = (char *)"admi";
664 result = Curl_parsenetrc("example.com", &login, &password,
665 &login_changed, &password_changed, filename);
666 fail_unless(result == 0, "Host should have been found");
667- abort_unless(password != NULL, "returned NULL!");
668- fail_unless(password[0] == 0, "password should not have been changed");
669- fail_unless(!password_changed, "password should not have been changed");
670- abort_unless(login != NULL, "returned NULL!");
671- fail_unless(strncmp(login, "admi", 4) == 0,
672- "login should not have been changed");
673- fail_unless(!login_changed, "login should not have been changed");
674+ abort_unless(password == NULL, "password is not NULL!");
675
676 /*
677 * Test a non existent login (superstring of an existing one)
678 * in our netrc file.
679 */
680- free(login);
681- login = strdup("adminn");
682- abort_unless(login != NULL, "returned NULL!");
683+ login = (char *)"adminn";
684 result = Curl_parsenetrc("example.com", &login, &password,
685 &login_changed, &password_changed, filename);
686 fail_unless(result == 0, "Host should have been found");
687- abort_unless(password != NULL, "returned NULL!");
688- fail_unless(password[0] == 0, "password should not have been changed");
689- fail_unless(!password_changed, "password should not have been changed");
690- abort_unless(login != NULL, "returned NULL!");
691- fail_unless(strncmp(login, "adminn", 6) == 0,
692- "login should not have been changed");
693- fail_unless(!login_changed, "login should not have been changed");
694+ abort_unless(password == NULL, "password is not NULL!");
695
696 /*
697 * Test for the first existing host in our netrc file
698 * with login[0] = 0.
699 */
700- free(login);
701- login = strdup("");
702- abort_unless(login != NULL, "returned NULL!");
703+ login = NULL;
704 result = Curl_parsenetrc("example.com", &login, &password,
705 &login_changed, &password_changed, filename);
706 fail_unless(result == 0, "Host should have been found");
707@@ -155,8 +116,9 @@ UNITTEST_START
708 * with login[0] != 0.
709 */
710 free(password);
711- password = strdup("");
712- abort_unless(password != NULL, "returned NULL!");
713+ free(login);
714+ password = NULL;
715+ login = NULL;
716 result = Curl_parsenetrc("example.com", &login, &password,
717 &login_changed, &password_changed, filename);
718 fail_unless(result == 0, "Host should have been found");
719@@ -173,11 +135,9 @@ UNITTEST_START
720 * with login[0] = 0.
721 */
722 free(password);
723- password = strdup("");
724- abort_unless(password != NULL, "returned NULL!");
725+ password = NULL;
726 free(login);
727- login = strdup("");
728- abort_unless(login != NULL, "returned NULL!");
729+ login = NULL;
730 result = Curl_parsenetrc("curl.example.com", &login, &password,
731 &login_changed, &password_changed, filename);
732 fail_unless(result == 0, "Host should have been found");
733@@ -194,8 +154,9 @@ UNITTEST_START
734 * with login[0] != 0.
735 */
736 free(password);
737- password = strdup("");
738- abort_unless(password != NULL, "returned NULL!");
739+ free(login);
740+ password = NULL;
741+ login = NULL;
742 result = Curl_parsenetrc("curl.example.com", &login, &password,
743 &login_changed, &password_changed, filename);
744 fail_unless(result == 0, "Host should have been found");
745--
7462.40.0
diff --git a/meta/recipes-support/curl/curl_7.82.0.bb b/meta/recipes-support/curl/curl_7.82.0.bb
index 748afc1235..f40139418a 100644
--- a/meta/recipes-support/curl/curl_7.82.0.bb
+++ b/meta/recipes-support/curl/curl_7.82.0.bb
@@ -63,6 +63,8 @@ SRC_URI = "https://curl.se/download/${BP}.tar.xz \
63 file://CVE-2024-8096.patch \ 63 file://CVE-2024-8096.patch \
64 file://0001-url-free-old-conn-better-on-reuse.patch \ 64 file://0001-url-free-old-conn-better-on-reuse.patch \
65 file://CVE-2024-9681.patch \ 65 file://CVE-2024-9681.patch \
66 file://CVE-2024-11053-0001.patch \
67 file://CVE-2024-11053-0002.patch \
66 " 68 "
67SRC_URI[sha256sum] = "0aaa12d7bd04b0966254f2703ce80dd5c38dbbd76af0297d3d690cdce58a583c" 69SRC_URI[sha256sum] = "0aaa12d7bd04b0966254f2703ce80dd5c38dbbd76af0297d3d690cdce58a583c"
68 70