From eb2cc34baf5297ad3384dc13421f4e0a4c8f9160 Mon Sep 17 00:00:00 2001 From: renwang Date: Thu, 19 Dec 2024 16:17:02 +0800 Subject: [PATCH] change --- backport-CVE-2024-52531.patch | 281 ++++++++++++++++++++++++++++++++++ libsoup3.spec | 9 +- 2 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2024-52531.patch diff --git a/backport-CVE-2024-52531.patch b/backport-CVE-2024-52531.patch new file mode 100644 index 0000000..5f9e5c7 --- /dev/null +++ b/backport-CVE-2024-52531.patch @@ -0,0 +1,281 @@ +From 298e6b4514fe84a1239e4940cea90acf0803ce3a Mon Sep 17 00:00:00 2001 +From: renwang +Date: Thu, 19 Dec 2024 10:13:54 +0800 +Subject: [PATCH] change + +--- + fuzzing/fuzz.h | 7 ++++- + fuzzing/fuzz_header_parsing.c | 19 ++++++++++++++ + fuzzing/fuzz_header_parsing.dict | 8 ++++++ + fuzzing/meson.build | 2 ++ + libsoup/soup-headers.c | 44 +++++++++++++++++--------------- + meson.build | 3 +++ + tests/header-parsing-test.c | 11 ++++++++ + tests/hsts-db-test.c | 4 ++- + tests/proxy-test.c | 4 ++- + 9 files changed, 79 insertions(+), 23 deletions(-) + create mode 100644 fuzzing/fuzz_header_parsing.c + create mode 100644 fuzzing/fuzz_header_parsing.dict + +diff --git a/fuzzing/fuzz.h b/fuzzing/fuzz.h +index 0d38028..7a6be84 100644 +--- a/fuzzing/fuzz.h ++++ b/fuzzing/fuzz.h +@@ -1,6 +1,7 @@ + #include "libsoup/soup.h" + + int LLVMFuzzerTestOneInput (const unsigned char *data, size_t size); ++static int set_logger = 0; + + #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + static GLogWriterOutput +@@ -16,6 +17,10 @@ static void + fuzz_set_logging_func (void) + { + #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +- g_log_set_writer_func (empty_logging_func, NULL, NULL); ++ if (!set_logger) ++ { ++ set_logger = 1; ++ g_log_set_writer_func (empty_logging_func, NULL, NULL); ++ } + #endif + } +diff --git a/fuzzing/fuzz_header_parsing.c b/fuzzing/fuzz_header_parsing.c +new file mode 100644 +index 0000000..a8e5c1f +--- /dev/null ++++ b/fuzzing/fuzz_header_parsing.c +@@ -0,0 +1,19 @@ ++#include "fuzz.h" ++ ++int ++LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) ++{ ++ GHashTable *elements; ++ ++ // We only accept NUL terminated strings ++ if (!size || data[size - 1] != '\0') ++ return 0; ++ ++ fuzz_set_logging_func (); ++ ++ elements = soup_header_parse_param_list((char*)data); ++ ++ g_hash_table_unref(elements); ++ ++ return 0; ++} +\ No newline at end of file +diff --git a/fuzzing/fuzz_header_parsing.dict b/fuzzing/fuzz_header_parsing.dict +new file mode 100644 +index 0000000..1562ca3 +--- /dev/null ++++ b/fuzzing/fuzz_header_parsing.dict +@@ -0,0 +1,8 @@ ++"*=UTF-8''" ++"*=iso-8859-1''" ++"'" ++"''" ++"=" ++"*=" ++""" ++";" +\ No newline at end of file +diff --git a/fuzzing/meson.build b/fuzzing/meson.build +index b14cbb5..e1d91c4 100644 +--- a/fuzzing/meson.build ++++ b/fuzzing/meson.build +@@ -5,6 +5,7 @@ fuzz_targets = [ + 'fuzz_cookie_parse', + 'fuzz_content_sniffer', + 'fuzz_date_time', ++ 'fuzz_header_parsing', + ] + + fuzzing_args = '-fsanitize=fuzzer,address,undefined' +@@ -34,6 +35,7 @@ if have_fuzzing and (fuzzing_feature.enabled() or fuzzing_feature.auto()) + '-runs=200000', + '-artifact_prefix=meson-logs/' + target + '-', + '-print_final_stats=1', ++ '-max_len=4096', + ] + extra_args, + env: [ + 'ASAN_OPTIONS=fast_unwind_on_malloc=0', +diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c +index 5485e62..e80b4ab 100644 +--- a/libsoup/soup-headers.c ++++ b/libsoup/soup-headers.c +@@ -660,8 +660,9 @@ soup_header_contains (const char *header, const char *token) + } + + static void +-decode_quoted_string (char *quoted_string) ++decode_quoted_string_inplace (GString *quoted_gstring) + { ++ char *quoted_string = quoted_gstring->str; + char *src, *dst; + + src = quoted_string + 1; +@@ -675,10 +676,11 @@ decode_quoted_string (char *quoted_string) + } + + static gboolean +-decode_rfc5987 (char *encoded_string) ++decode_rfc5987_inplace (GString *encoded_gstring) + { + char *q, *decoded; + gboolean iso_8859_1 = FALSE; ++ const char *encoded_string = encoded_gstring->str; + + q = strchr (encoded_string, '\''); + if (!q) +@@ -710,14 +712,7 @@ decode_rfc5987 (char *encoded_string) + decoded = utf8; + } + +- /* If encoded_string was UTF-8, then each 3-character %-escape +- * will be converted to a single byte, and so decoded is +- * shorter than encoded_string. If encoded_string was +- * iso-8859-1, then each 3-character %-escape will be +- * converted into at most 2 bytes in UTF-8, and so it's still +- * shorter. +- */ +- strcpy (encoded_string, decoded); ++ g_string_assign (encoded_gstring, decoded); + g_free (decoded); + return TRUE; + } +@@ -732,10 +727,14 @@ parse_param_list (const char *header, char delim, gboolean strict) + + params = g_hash_table_new_full (soup_str_case_hash, + soup_str_case_equal, +- g_free, NULL); ++ g_free, g_free); + + list = parse_list (header, delim); + for (iter = list; iter; iter = iter->next) { ++ char *item, *eq, *name_end; ++ gboolean override, duplicated; ++ GString *parsed_value = NULL; ++ + item = iter->data; + override = FALSE; + +@@ -750,19 +749,19 @@ parse_param_list (const char *header, char delim, gboolean strict) + + *name_end = '\0'; + +- value = (char *)skip_lws (eq + 1); ++ parsed_value = g_string_new ((char *)skip_lws (eq + 1)); + + if (name_end[-1] == '*' && name_end > item + 1) { + name_end[-1] = '\0'; +- if (!decode_rfc5987 (value)) { ++ if (!decode_rfc5987_inplace (parsed_value)) { ++ g_string_free (parsed_value, TRUE); + g_free (item); + continue; + } + override = TRUE; +- } else if (*value == '"') +- decode_quoted_string (value); +- } else +- value = NULL; ++ } else if (parsed_value->str[0] == '"') ++ decode_quoted_string_inplace (parsed_value); ++ } + + duplicated = g_hash_table_lookup_extended (params, item, NULL, NULL); + +@@ -770,11 +769,16 @@ parse_param_list (const char *header, char delim, gboolean strict) + soup_header_free_param_list (params); + params = NULL; + g_slist_foreach (iter, (GFunc)g_free, NULL); ++ if (parsed_value) ++ g_string_free (parsed_value, TRUE); + break; +- } else if (override || !duplicated) +- g_hash_table_replace (params, item, value); +- else ++ } else if (override || !duplicated) { ++ g_hash_table_replace (params, item, parsed_value ? g_string_free (parsed_value, FALSE) : NULL); ++ } else { ++ if (parsed_value) ++ g_string_free (parsed_value, TRUE); + g_free (item); ++ } + } + + g_slist_free (list); +diff --git a/meson.build b/meson.build +index 20a9b51..a53d98c 100644 +--- a/meson.build ++++ b/meson.build +@@ -126,6 +126,9 @@ endif + + cdata = configuration_data() + ++cdata.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_70') ++cdata.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_70') ++ + brotlidec_dep = dependency('libbrotlidec', required : get_option('brotli')) + if brotlidec_dep.found() + cdata.set('WITH_BROTLI', true) +diff --git a/tests/header-parsing-test.c b/tests/header-parsing-test.c +index 7f324b7..ee0ccae 100644 +--- a/tests/header-parsing-test.c ++++ b/tests/header-parsing-test.c +@@ -831,6 +831,17 @@ static struct ParamListTest { + { "filename", "t\xC3\xA9st.txt" }, + }, + }, ++ ++ /* This tests invalid UTF-8 data which *should* never be passed here but it was designed to be robust against it. */ ++ { TRUE, ++ "invalid*=\x69\x27\x27\x93\x93\x93\x93\xff\x61\x61\x61\x61\x61\x61\x61\x62\x63\x64\x65\x0a; filename*=iso-8859-1''\x69\x27\x27\x93\x93\x93\x93\xff\x61\x61\x61\x61\x61\x61\x61\x62\x63\x64\x65\x0a; foo", ++ { ++ { "filename", "i''\302\223\302\223\302\223\302\223\303\277aaaaaaabcde" }, ++ { "invalid", "\302\223\302\223\302\223\302\223\303\277aaaaaaabcde" }, ++ { "foo", NULL }, ++ ++ }, ++ } + }; + static const int num_paramlisttests = G_N_ELEMENTS (paramlisttests); + +diff --git a/tests/hsts-db-test.c b/tests/hsts-db-test.c +index 1149a04..0af386f 100644 +--- a/tests/hsts-db-test.c ++++ b/tests/hsts-db-test.c +@@ -1,8 +1,10 @@ ++#include "test-utils.h" ++ + #include + #include + + #include +-#include "test-utils.h" ++ + #include "soup-uri-utils-private.h" + + #define DB_FILE "hsts-db.sqlite" +diff --git a/tests/proxy-test.c b/tests/proxy-test.c +index 9ca8699..a52e9b6 100644 +--- a/tests/proxy-test.c ++++ b/tests/proxy-test.c +@@ -1,8 +1,10 @@ + /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +-#include ++ + #include "test-utils.h" + ++#include ++ + typedef struct { + const char *explanation; + const char *url; +-- +2.20.1 + diff --git a/libsoup3.spec b/libsoup3.spec index f3f5b7b..a4ebea2 100644 --- a/libsoup3.spec +++ b/libsoup3.spec @@ -2,12 +2,13 @@ Name: libsoup3 Version: 3.0.6 -Release: 1 +Release: 2 Summary: Soup, an HTTP library implementation License: LGPLv2 URL: https://wiki.gnome.org/Projects/libsoup Source0: https://download.gnome.org/sources/libsoup/3.0/libsoup-%{version}.tar.xz Patch0: xgettext.patch +Patch1: backport-CVE-2024-52531.patch BuildRequires: gcc meson gettext vala gtk-doc krb5-devel samba-winbind-clients BuildRequires: pkgconfig(glib-2.0) @@ -75,5 +76,11 @@ you to develop applications that use the libsoup library. %{_datadir}/gtk-doc/html/libsoup-3.0 %changelog +* Thu Dec 19 2024 renwang - 3.0.6-2 +- Type:CVE +- ID:CVE-2024-52531 +- SUG:NA +- DESC:fix CVE-2024-52531 + * Mon Apr 11 2022 lin zhang - 3.0.6-1 - Initial packaging -- Gitee