!364 [sync] PR-361: fix CVE-2024-11053

From: @openeuler-sync-bot 
Reviewed-by: @jiangheng12 
Signed-off-by: @jiangheng12
This commit is contained in:
openeuler-ci-bot 2025-01-03 08:56:56 +00:00 committed by Gitee
commit e809167868
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 366 additions and 1 deletions

View File

@ -0,0 +1,358 @@
From e9b9bbac22c26cf67316fa8e6c6b9e831af31949 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 15 Nov 2024 11:06:36 +0100
Subject: [PATCH] netrc: address several netrc parser flaws
- make sure that a match that returns a username also returns a
password, that should be blank if no password is found
- fix handling of multiple logins for same host where the password/login
order might be reversed.
- reject credentials provided in the .netrc if they contain ASCII control
codes - if the used protocol does not support such (like HTTP and WS do)
Reported-by: Harry Sintonen
Add test 478, 479 and 480 to verify. Updated unit 1304.
Closes #15586
Conflict:context adapt
remove some code irrelevant with CVE
Reference:https://github.com/curl/curl/commit/e9b9bbac22c26cf67316fa8e6c6b9e831af31949
---
lib/netrc.c | 19 ++++++++++++++++++
tests/data/Makefile.inc | 1 +
tests/data/test479 | 107 ++++++++++++++++++++++++++++++++++++++
tests/unit/unit1304.c | 75 ++++++++-------------------
3 files changed, 180 insertions(+), 20 deletions(-)
create mode 100644 tests/data/test478
create mode 100644 tests/data/test479
create mode 100644 tests/data/test480
diff --git a/lib/netrc.c b/lib/netrc.c
index b771b60..9e183a2 100644
--- a/lib/netrc.c
+++ b/lib/netrc.c
@@ -152,6 +152,7 @@ static int parsenetrc(const char *host,
retcode = NETRC_FAILED; /* allocation failed */
goto out;
}
+ state_our_login = TRUE;
login_alloc = TRUE;
}
state_login = 0;
@@ -181,6 +182,16 @@ static int parsenetrc(const char *host,
state = HOSTFOUND;
state_our_login = FALSE;
}
+ else if(strcasecompare("default", tok)) {
+ state = HOSTVALID;
+ retcode = NETRC_SUCCESS; /* we did find our host */
+ Curl_safefree(password);
+ if(!specific_login)
+ if(login_alloc) {
+ free(login);
+ login_alloc = FALSE;
+ }
+ }
break;
} /* switch (state) */
@@ -189,6 +200,14 @@ static int parsenetrc(const char *host,
} /* while fgets() */
out:
+ if(!retcode && !password && state_our_login) {
+ /* success without a password, set a blank one */
+ password = strdup("");
+ if(!password)
+ retcode = 1; /* out of memory */
+ else
+ password_alloc = TRUE;
+ }
if(!retcode) {
/* success */
*login_changed = FALSE;
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index ea5221c00fd419..53f62c6e28f650 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -77,6 +77,7 @@ test435 test436 test437 test438 test439 test440 test441 test442 test443 \
test430 test431 test432 test433 test434 test435 test445 test446\
\
test442 test443 test444 \
+test479 \
test490 test491 test492 test493 test494 \
\
test500 test501 test502 test503 test504 test505 test506 test507 test508 \
diff --git a/tests/data/test479 b/tests/data/test479
new file mode 100644
index 00000000000000..d7ce4652fae272
--- /dev/null
+++ b/tests/data/test479
@@ -0,0 +1,107 @@
+<testcase>
+<info>
+<keywords>
+netrc
+HTTP
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data crlf="yes">
+HTTP/1.1 301 Follow this you fool
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Location: http://b.com/%TESTNUMBER0002
+
+-foo-
+</data>
+
+<data2 crlf="yes">
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 7
+Connection: close
+
+target
+</data2>
+
+<datacheck crlf="yes">
+HTTP/1.1 301 Follow this you fool
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Location: http://b.com/%TESTNUMBER0002
+
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 7
+Connection: close
+
+target
+</datacheck>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<features>
+proxy
+</features>
+<name>
+.netrc with redirect and default without password
+</name>
+<command>
+--netrc --netrc-file log/netrc%TESTNUMBER -L -x http://%HOSTIP:%HTTPPORT/ http://a.com/
+</command>
+<file name="log/netrc%TESTNUMBER" >
+
+machine a.com
+ login alice
+ password alicespassword
+
+default
+ login bob
+
+</file>
+</client>
+
+<verify>
+<protocol>
+GET http://a.com/ HTTP/1.1
+Host: a.com
+Authorization: Basic %b64[alice:alicespassword]b64%
+User-Agent: curl/%VERSION
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+GET http://b.com/%TESTNUMBER0002 HTTP/1.1
+Host: b.com
+Authorization: Basic %b64[bob:]b64%
+User-Agent: curl/%VERSION
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/unit/unit1304.c b/tests/unit/unit1304.c
index 238d3c0f7fb09a..817887b94c8748 100644
--- a/tests/unit/unit1304.c
+++ b/tests/unit/unit1304.c
@@ -32,13 +32,8 @@ static char *password;
static CURLcode unit_setup(void)
{
- password = strdup("");
- login = strdup("");
- if(!password || !login) {
- Curl_safefree(password);
- Curl_safefree(login);
- return CURLE_OUT_OF_MEMORY;
- }
+ password = NULL;
+ login = NULL;
return CURLE_OK;
}
@@ -60,86 +55,52 @@ UNITTEST_START
result = Curl_parsenetrc("test.example.com", &login, &password,
&login_changed, &password_changed, filename);
fail_unless(result == 1, "Host not found should return 1");
- abort_unless(password != NULL, "returned NULL!");
- fail_unless(password[0] == 0, "password should not have been changed");
- abort_unless(login != NULL, "returned NULL!");
- fail_unless(login[0] == 0, "login should not have been changed");
+ abort_unless(password == NULL, "password did not return NULL!");
+ abort_unless(login == NULL, "user did not return NULL!");
/*
* Test a non existent login in our netrc file.
*/
- free(login);
- login = strdup("me");
- abort_unless(login != NULL, "returned NULL!");
+ login = (char *)"me";
result = Curl_parsenetrc("example.com", &login, &password,
&login_changed, &password_changed, filename);
fail_unless(result == 0, "Host should have been found");
- abort_unless(password != NULL, "returned NULL!");
- fail_unless(password[0] == 0, "password should not have been changed");
- fail_unless(!password_changed, "password should not have been changed");
- abort_unless(login != NULL, "returned NULL!");
- fail_unless(strncmp(login, "me", 2) == 0,
- "login should not have been changed");
- fail_unless(!login_changed, "login should not have been changed");
+ abort_unless(password == NULL, "password is not NULL!");
/*
* Test a non existent login and host in our netrc file.
*/
- free(login);
- login = strdup("me");
- abort_unless(login != NULL, "returned NULL!");
+ login = (char *)"me";
result = Curl_parsenetrc("test.example.com", &login, &password,
&login_changed, &password_changed, filename);
fail_unless(result == 1, "Host not found should return 1");
- abort_unless(password != NULL, "returned NULL!");
- fail_unless(password[0] == 0, "password should not have been changed");
- abort_unless(login != NULL, "returned NULL!");
- fail_unless(strncmp(login, "me", 2) == 0,
- "login should not have been changed");
+ abort_unless(password == NULL, "password is not NULL!");
/*
* Test a non existent login (substring of an existing one) in our
* netrc file.
*/
- free(login);
- login = strdup("admi");
- abort_unless(login != NULL, "returned NULL!");
+ login = (char *)"admi";
result = Curl_parsenetrc("example.com", &login, &password,
&login_changed, &password_changed, filename);
fail_unless(result == 0, "Host should have been found");
- abort_unless(password != NULL, "returned NULL!");
- fail_unless(password[0] == 0, "password should not have been changed");
- fail_unless(!password_changed, "password should not have been changed");
- abort_unless(login != NULL, "returned NULL!");
- fail_unless(strncmp(login, "admi", 4) == 0,
- "login should not have been changed");
- fail_unless(!login_changed, "login should not have been changed");
+ abort_unless(password == NULL, "password is not NULL!");
/*
* Test a non existent login (superstring of an existing one)
* in our netrc file.
*/
- free(login);
- login = strdup("adminn");
- abort_unless(login != NULL, "returned NULL!");
+ login = (char *)"adminn";
result = Curl_parsenetrc("example.com", &login, &password,
&login_changed, &password_changed, filename);
fail_unless(result == 0, "Host should have been found");
- abort_unless(password != NULL, "returned NULL!");
- fail_unless(password[0] == 0, "password should not have been changed");
- fail_unless(!password_changed, "password should not have been changed");
- abort_unless(login != NULL, "returned NULL!");
- fail_unless(strncmp(login, "adminn", 6) == 0,
- "login should not have been changed");
- fail_unless(!login_changed, "login should not have been changed");
+ abort_unless(password == NULL, "password is not NULL!");
/*
* Test for the first existing host in our netrc file
* with login[0] = 0.
*/
- free(login);
- login = strdup("");
- abort_unless(login != NULL, "returned NULL!");
+ login = NULL;
result = Curl_parsenetrc("example.com", &login, &password,
&login_changed, &password_changed, filename);
fail_unless(result == 0, "Host should have been found");
@@ -159,8 +126,9 @@ UNITTEST_START
* with login[0] != 0.
*/
free(password);
- password = strdup("");
- abort_unless(password != NULL, "returned NULL!");
+ free(login);
+ password = NULL;
+ login = NULL;
result = Curl_parsenetrc("example.com", &login, &password,
&login_changed, &password_changed, filename);
fail_unless(result == 0, "Host should have been found");
@@ -177,11 +145,9 @@ UNITTEST_START
* with login[0] = 0.
*/
free(password);
- password = strdup("");
- abort_unless(password != NULL, "returned NULL!");
+ password = NULL;
free(login);
- login = strdup("");
- abort_unless(login != NULL, "returned NULL!");
+ login = NULL;
result = Curl_parsenetrc("curl.example.com", &login, &password,
&login_changed, &password_changed, filename);
fail_unless(result == 0, "Host should have been found");
@@ -198,8 +164,9 @@ UNITTEST_START
* with login[0] != 0.
*/
free(password);
- password = strdup("");
- abort_unless(password != NULL, "returned NULL!");
+ free(login);
+ password = NULL;
+ login = NULL;
result = Curl_parsenetrc("curl.example.com", &login, &password,
&login_changed, &password_changed, filename);
fail_unless(result == 0, "Host should have been found");

View File

@ -6,7 +6,7 @@
Name: curl
Version: 7.79.1
Release: 35
Release: 36
Summary: Curl is used in command lines or scripts to transfer data
License: MIT
URL: https://curl.haxx.se/
@ -110,6 +110,7 @@ Patch96: backport-url-allow-DoH-transfers-to-override-max-connection-limi
Patch97: backport-CVE-2024-9681.patch
Patch98: backport-multi-check-that-the-multi-handle-is-valid-in-curl_m.patch
Patch99: backport-cookie-treat-cookie-name-case-sensitively.patch
Patch100: backport-CVE-2024-11053.patch
BuildRequires: automake brotli-devel coreutils gcc groff krb5-devel
BuildRequires: libidn2-devel libnghttp2-devel libpsl-devel
@ -278,6 +279,12 @@ rm -rf ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la
%{_mandir}/man3/*
%changelog
* Fri Jan 03 2025 zhouyihang <zhouyihang3@h-partners.com> - 7.79.1-36
- Type:CVE
- CVE:CVE-2024-11053
- SUG:NA
- DESC:fix CVE-2024-11053
* Mon Dec 09 2024 zhouyihang <zhouyihang3@h-partners.com> - 7.79.1-35
- Type:bugfix
- CVE:NA