From: Nicholas Wilson Date: Sat, 25 Oct 2025 09:50:27 +0000 (+0100) Subject: Backport of pcre2-10.48-Write-serialization-padding.patch X-Git-Tag: archive/raspbian/10.46-1_deb13u2+rpi1^2~10 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=de0a195fe719f62ec57bd6103c9ac73e68fab49a;p=pcre2.git Backport of pcre2-10.48-Write-serialization-padding.patch Cherry-pick of edc111a6831591f68b5355a08cc9df8be8f35304 Write padding values to ensure pcre2_serialize_encode() outputs defined values (#826) Fixes low-severity valgrind error reported in GHSA-q7rw-r7qq-2hx6. (cherry picked from commit efeabb2dc9adfb91abf8feecd8daccb2a38ea94f) --- diff --git a/src/pcre2_compile_class.c b/src/pcre2_compile_class.c index 6a73bb9..b710877 100644 --- a/src/pcre2_compile_class.c +++ b/src/pcre2_compile_class.c @@ -1774,17 +1774,14 @@ if ((xclass_props & XCLASS_REQUIRED) != 0) PUT(code, 0, (uint32_t)(char_lists_size >> 1)); code += LINK_SIZE; -#if defined PCRE2_DEBUG || defined SUPPORT_VALGRIND + /* If we added padding to align the list, initialize the bytes to + defined values, so the library is valgrind-clean. It could also + be a security concern for clients calling into PCRE2 via bindings + from a memory-safe language, if pcre2_serialize_encode() exposes + uninitialized memory that may contain sensitive information. */ + if ((char_lists_size & 0x2) != 0) - { - /* In debug the unused 16 bit value is set - to a fixed value and marked unused. */ - ((uint16_t*)data)[-1] = 0x5555; -#ifdef SUPPORT_VALGRIND - VALGRIND_MAKE_MEM_NOACCESS(data - 2, 2); -#endif - } -#endif + ((uint16_t*)data)[-1] = 0xdead; cb->char_lists_size = CLIST_ALIGN_TO(char_lists_size, sizeof(uint32_t)); diff --git a/src/pcre2test.c b/src/pcre2test.c index 7e3c979..a6696bc 100644 --- a/src/pcre2test.c +++ b/src/pcre2test.c @@ -5414,6 +5414,10 @@ uint32_t use_forbid_utf = forbid_utf; PCRE2_SIZE patlen; PCRE2_SIZE valgrind_access_length; PCRE2_SIZE erroroffset; +int32_t serialize_rc; +void *serialize_code; +uint8_t *serialized_bytes; +PCRE2_SIZE serialized_size; /* The perltest.sh script supports only / as a delimiter. */ @@ -6259,6 +6263,29 @@ if ((pat_patctl.control2 & CTL2_NL_SET) != 0) rc = show_pattern_info(); if (rc != PR_OK) return rc; +/* Verify that the compiled structure can be serialized without generating +memory errors. */ + +serialize_code = PTR(compiled_code); +PCRE2_SERIALIZE_ENCODE(serialize_rc, &serialize_code, 1, &serialized_bytes, + &serialized_size, general_context); +if (serialize_rc != 1) + { + fprintf(outfile, "** pcre2_serialize_encode() returned %d instead of 1\n", + serialize_rc); + return PR_ABEND; + } + +#if defined SUPPORT_VALGRIND +if (VALGRIND_CHECK_MEM_IS_DEFINED(serialized_bytes, serialized_size) != 0) + { + fprintf(outfile, "** pcre2_serialize_encode() returned undefined data\n"); + return PR_ABEND; + } +#endif + +PCRE2_SERIALIZE_FREE(serialized_bytes); + /* The "push" control requests that the compiled pattern be remembered on a stack. This is mainly for testing the serialization functionality. */