diff --git a/SOURCES/0001-headers-Strictly-don-t-allow-NUL-bytes.patch b/SOURCES/0001-headers-Strictly-don-t-allow-NUL-bytes.patch new file mode 100644 index 0000000..8e24c6a --- /dev/null +++ b/SOURCES/0001-headers-Strictly-don-t-allow-NUL-bytes.patch @@ -0,0 +1,129 @@ +diff -up libsoup-2.62.2/libsoup/soup-headers.c.cve-2024-52530 libsoup-2.62.2/libsoup/soup-headers.c +--- libsoup-2.62.2/libsoup/soup-headers.c.cve-2024-52530 2018-03-23 14:44:54.000000000 +0100 ++++ libsoup-2.62.2/libsoup/soup-headers.c 2024-11-12 10:23:16.693272087 +0100 +@@ -50,13 +50,14 @@ soup_headers_parse (const char *str, int + * ignorable trailing whitespace. + */ + ++ /* No '\0's are allowed */ ++ if (memchr (str, '\0', len)) ++ return FALSE; ++ + /* Skip over the Request-Line / Status-Line */ + headers_start = memchr (str, '\n', len); + if (!headers_start) + return FALSE; +- /* No '\0's in the Request-Line / Status-Line */ +- if (memchr (str, '\0', headers_start - str)) +- return FALSE; + + /* We work on a copy of the headers, which we can write '\0's + * into, so that we don't have to individually g_strndup and +@@ -68,14 +69,6 @@ soup_headers_parse (const char *str, int + headers_copy[copy_len] = '\0'; + value_end = headers_copy; + +- /* There shouldn't be any '\0's in the headers already, but +- * this is the web we're talking about. +- */ +- while ((p = memchr (headers_copy, '\0', copy_len))) { +- memmove (p, p + 1, copy_len - (p - headers_copy)); +- copy_len--; +- } +- + while (*(value_end + 1)) { + name = value_end + 1; + name_end = strchr (name, ':'); +diff -up libsoup-2.62.2/tests/header-parsing.c.cve-2024-52530 libsoup-2.62.2/tests/header-parsing.c +--- libsoup-2.62.2/tests/header-parsing.c.cve-2024-52530 2024-11-12 10:25:26.452447520 +0100 ++++ libsoup-2.62.2/tests/header-parsing.c 2024-11-12 10:28:05.738158891 +0100 +@@ -358,24 +358,6 @@ static struct RequestTest { + } + }, + +- { "NUL in header name", "760832", +- "GET / HTTP/1.1\r\nHost\x00: example.com\r\n", 36, +- SOUP_STATUS_OK, +- "GET", "/", SOUP_HTTP_1_1, +- { { "Host", "example.com" }, +- { NULL } +- } +- }, +- +- { "NUL in header value", "760832", +- "GET / HTTP/1.1\r\nHost: example\x00" "com\r\n", 35, +- SOUP_STATUS_OK, +- "GET", "/", SOUP_HTTP_1_1, +- { { "Host", "examplecom" }, +- { NULL } +- } +- }, +- + /************************/ + /*** INVALID REQUESTS ***/ + /************************/ +@@ -448,6 +430,21 @@ static struct RequestTest { + SOUP_STATUS_EXPECTATION_FAILED, + NULL, NULL, -1, + { { NULL } } ++ }, ++ ++ // https://gitlab.gnome.org/GNOME/libsoup/-/issues/377 ++ { "NUL in header name", NULL, ++ "GET / HTTP/1.1\r\nHost\x00: example.com\r\n", 36, ++ SOUP_STATUS_BAD_REQUEST, ++ NULL, NULL, -1, ++ { { NULL } } ++ }, ++ ++ { "NUL in header value", NULL, ++ "HTTP/1.1 200 OK\r\nFoo: b\x00" "ar\r\n", 28, ++ SOUP_STATUS_BAD_REQUEST, ++ NULL, NULL, -1, ++ { { NULL } } + } + }; + static const int num_reqtests = G_N_ELEMENTS (reqtests); +@@ -620,22 +617,6 @@ static struct ResponseTest { + { NULL } } + }, + +- { "NUL in header name", "760832", +- "HTTP/1.1 200 OK\r\nF\x00oo: bar\r\n", 28, +- SOUP_HTTP_1_1, SOUP_STATUS_OK, "OK", +- { { "Foo", "bar" }, +- { NULL } +- } +- }, +- +- { "NUL in header value", "760832", +- "HTTP/1.1 200 OK\r\nFoo: b\x00" "ar\r\n", 28, +- SOUP_HTTP_1_1, SOUP_STATUS_OK, "OK", +- { { "Foo", "bar" }, +- { NULL } +- } +- }, +- + /********************************/ + /*** VALID CONTINUE RESPONSES ***/ + /********************************/ +@@ -768,6 +749,19 @@ static struct ResponseTest { + { { NULL } + } + }, ++ ++ // https://gitlab.gnome.org/GNOME/libsoup/-/issues/377 ++ { "NUL in header name", NULL, ++ "HTTP/1.1 200 OK\r\nF\x00oo: bar\r\n", 28, ++ -1, 0, NULL, ++ { { NULL } } ++ }, ++ ++ { "NUL in header value", "760832", ++ "HTTP/1.1 200 OK\r\nFoo: b\x00" "ar\r\n", 28, ++ -1, 0, NULL, ++ { { NULL } } ++ }, + }; + static const int num_resptests = G_N_ELEMENTS (resptests); + diff --git a/SOURCES/0001-websocket-process-the-frame-as-soon-as-we-read-data.patch b/SOURCES/0001-websocket-process-the-frame-as-soon-as-we-read-data.patch new file mode 100644 index 0000000..cc2d173 --- /dev/null +++ b/SOURCES/0001-websocket-process-the-frame-as-soon-as-we-read-data.patch @@ -0,0 +1,15 @@ +diff -up libsoup-2.62.3/libsoup/soup-websocket-connection.c.cve-2024-52532 libsoup-2.62.3/libsoup/soup-websocket-connection.c +--- libsoup-2.62.3/libsoup/soup-websocket-connection.c.cve-2024-52532 2024-11-12 12:00:27.183570627 +0100 ++++ libsoup-2.62.3/libsoup/soup-websocket-connection.c 2024-11-12 12:01:02.334987409 +0100 +@@ -1041,9 +1041,9 @@ soup_websocket_connection_read (SoupWebs + } + + pv->incoming->len = len + count; +- } while (count > 0); ++ process_incoming (self); ++ } while (count > 0 && !pv->close_sent && !pv->io_closing); + +- process_incoming (self); + + if (end) { + if (!pv->close_sent || !pv->close_received) { diff --git a/SPECS/libsoup.spec b/SPECS/libsoup.spec index bff9d7a..93c4d17 100644 --- a/SPECS/libsoup.spec +++ b/SPECS/libsoup.spec @@ -2,7 +2,7 @@ Name: libsoup Version: 2.62.3 -Release: 4%{?dist} +Release: 6%{?dist} Summary: Soup, an HTTP library implementation License: LGPLv2 @@ -14,6 +14,8 @@ Patch0002: 0002-WebSockets-allow-null-characters-in-text-messages-da.patch Patch0003: 0003-WebSockets-only-poll-IO-stream-when-needed.patch Patch0004: 0004-ntlmv2.patch Patch0005: 0005-WebSockets-do-not-start-the-input-source-when-IO-is-closing.patch +Patch0006: 0001-headers-Strictly-don-t-allow-NUL-bytes.patch +Patch0007: 0001-websocket-process-the-frame-as-soon-as-we-read-data.patch BuildRequires: chrpath BuildRequires: glib2-devel >= %{glib2_version} @@ -23,7 +25,7 @@ BuildRequires: krb5-devel >= 1.11 BuildRequires: pkgconfig(gobject-introspection-1.0) BuildRequires: pkgconfig(libxml-2.0) BuildRequires: pkgconfig(sqlite3) -BuildRequires: %{_bindir}/python3 +BuildRequires: python3-devel BuildRequires: vala Requires: glib2%{?_isa} >= %{glib2_version} @@ -88,6 +90,15 @@ chrpath --delete $RPM_BUILD_ROOT%{_libdir}/*.so %{_datadir}/vala/vapi/libsoup-2.4.vapi %changelog +* Tue Nov 12 2024 Tomas Popela - 2.62.3-6 +- Backport upstream patch for CVE-2024-52530 - HTTP request smuggling via stripping null bytes from the ends of header names +- Backport upstream patch for CVE-2024-52530 - infinite loop while reading websocket data +- Resolves: RHEL-67076 +- Resolves: RHEL-67067 + +* Tue Sep 05 2023 Milan Crha - 2.62.3-5 +- Resolves: RHEL-2240 (Correct BuildRequires for python3) + * Wed Jul 26 2023 MSVSphere Packaging Team - 2.62.3-4 - Rebuilt for MSVSphere 8.8