Skip to content

Commit edc111a

Browse files
authored
Write padding values to ensure pcre2_serialize_encode() outputs defined values (#826)
Fixes low-severity valgrind error reported in GHSA-q7rw-r7qq-2hx6.
1 parent a5dc178 commit edc111a

File tree

2 files changed

+32
-10
lines changed

2 files changed

+32
-10
lines changed

src/pcre2_compile_class.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,17 +1802,14 @@ if ((xclass_props & XCLASS_REQUIRED) != 0)
18021802
PUT(code, 0, (uint32_t)(char_lists_size >> 1));
18031803
code += LINK_SIZE;
18041804

1805-
#if defined PCRE2_DEBUG || defined SUPPORT_VALGRIND
1805+
/* If we added padding to align the list, initialize the bytes to
1806+
defined values, so the library is valgrind-clean. It could also
1807+
be a security concern for clients calling into PCRE2 via bindings
1808+
from a memory-safe language, if pcre2_serialize_encode() exposes
1809+
uninitialized memory that may contain sensitive information. */
1810+
18061811
if ((char_lists_size & 0x2) != 0)
1807-
{
1808-
/* In debug the unused 16 bit value is set
1809-
to a fixed value and marked unused. */
1810-
((uint16_t*)data)[-1] = 0x5555;
1811-
#ifdef SUPPORT_VALGRIND
1812-
VALGRIND_MAKE_MEM_NOACCESS(data - 2, 2);
1813-
#endif
1814-
}
1815-
#endif
1812+
((uint16_t*)data)[-1] = 0xdead;
18161813

18171814
cb->char_lists_size =
18181815
CLIST_ALIGN_TO(char_lists_size, sizeof(uint32_t));

src/pcre2test_inc.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,6 +2019,9 @@ uint32_t use_forbid_utf = forbid_utf;
20192019
PCRE2_SIZE patlen, full_patlen;
20202020
PCRE2_SIZE valgrind_access_length;
20212021
PCRE2_SIZE erroroffset;
2022+
int32_t serialize_rc;
2023+
uint8_t *serialized_bytes;
2024+
PCRE2_SIZE serialized_size;
20222025

20232026
/* The perltest.sh script supports only / as a delimiter. */
20242027

@@ -2966,6 +2969,28 @@ if ((pat_patctl.control2 & CTL2_NL_SET) != 0)
29662969
rc = show_pattern_info();
29672970
if (rc != PR_OK) return rc;
29682971

2972+
/* Verify that the compiled structure can be serialized without generating
2973+
memory errors. */
2974+
2975+
serialize_rc = pcre2_serialize_encode((const pcre2_code **)&compiled_code, 1,
2976+
&serialized_bytes, &serialized_size, general_context);
2977+
if (serialize_rc != 1)
2978+
{
2979+
cfprintf(clr_test_error, outfile, "** pcre2_serialize_encode() returned %d instead of 1\n",
2980+
serialize_rc);
2981+
return PR_ABEND;
2982+
}
2983+
2984+
#if defined SUPPORT_VALGRIND
2985+
if (VALGRIND_CHECK_MEM_IS_DEFINED(serialized_bytes, serialized_size) != 0)
2986+
{
2987+
cfprintf(clr_test_error, outfile, "** pcre2_serialize_encode() returned undefined data\n");
2988+
return PR_ABEND;
2989+
}
2990+
#endif
2991+
2992+
pcre2_serialize_free(serialized_bytes);
2993+
29692994
/* The "push" control requests that the compiled pattern be remembered on a
29702995
stack. This is mainly for testing the serialization functionality. */
29712996

0 commit comments

Comments
 (0)