This is an automated email from the ASF dual-hosted git repository. reshke pushed a commit to branch backport_cve in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit 16364f5175be793cd1442cab9dce53c1ac447d5c Author: Masahiko Sawada <[email protected]> AuthorDate: Mon Aug 10 06:38:23 2026 -0700 Fix potential buffer overrun in regexp match/split functions. setup_regexp_matches() sizes the buffer used to convert matched substrings back from pg_wchar form at the smaller of maxlen*eml and the original string's byte length, on the assumption that such a conversion cannot produce more bytes than the string it came from. That assumption holds only for validly encoded input. But pg_mb2wchar_with_len() silently accepts bytes that are invalid in the database encoding, turning each such byte into one pg_wchar, and converting that back can take more bytes than the input did. A string made of such bytes therefore overruns the conversion buffer by up to its own length, corrupting the following memory. regexp_match(), regexp_matches(), regexp_split_to_table() and regexp_split_to_array() are all affected. Fix by dropping the tighter bound and always allocating maxlen*eml + 1 bytes. Reported-by: Francesco Verardi <[email protected]> Author: Masahiko Sawada <[email protected]> Reviewed-by: Tom Lane <[email protected]> Backpatch-through: 14 Security: CVE-2026-14664 --- src/backend/utils/adt/regexp.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/backend/utils/adt/regexp.c b/src/backend/utils/adt/regexp.c index d43a0577ee4..e0e0bc0bfac 100644 --- a/src/backend/utils/adt/regexp.c +++ b/src/backend/utils/adt/regexp.c @@ -1444,7 +1444,7 @@ setup_regexp_matches(text *orig_str, text *pattern, pg_re_flags *re_flags, /* convert string to pg_wchar form for matching */ orig_len = VARSIZE_ANY_EXHDR(orig_str); - wide_str = (pg_wchar *) palloc(sizeof(pg_wchar) * (orig_len + 1)); + wide_str = palloc_array(pg_wchar, orig_len + 1); wide_len = pg_mb2wchar_with_len(VARDATA_ANY(orig_str), wide_str, orig_len); /* set up the compiled pattern */ @@ -1580,23 +1580,24 @@ setup_regexp_matches(text *orig_str, text *pattern, pg_re_flags *re_flags, if (eml > 1) { - int64 maxsiz = eml * (int64) maxlen; int conv_bufsiz; /* * Make the conversion buffer large enough for any substring of - * interest. + * interest. We can't use the original string's byte length as a + * tighter bound, because that assumes the input is validly encoded; + * but pg_mb2wchar_with_len() can accept strings that are invalid in + * the database encoding, and converting such a character back to + * multibyte form can take more bytes than it did in the input. * - * Worst case: assume we need the maximum size (maxlen*eml), but take - * advantage of the fact that the original string length in bytes is - * an upper bound on the byte length of any fetched substring (and we - * know that len+1 is safe to allocate because the varlena header is - * longer than 1 byte). + * This can't overflow, nor exceed what palloc will accept: maxlen is + * at most wide_len, which is at most orig_len, and we have already + * successfully allocated (orig_len + 1) * sizeof(pg_wchar) bytes for + * wide_str. That relies on eml being no more than sizeof(pg_wchar), + * which is true of all supported encodings. */ - if (maxsiz > orig_len) - conv_bufsiz = orig_len + 1; - else - conv_bufsiz = maxsiz + 1; /* safe since maxsiz < 2^30 */ + Assert(eml <= sizeof(pg_wchar)); + conv_bufsiz = maxlen * eml + 1; matchctx->conv_buf = palloc(conv_bufsiz); matchctx->conv_bufsiz = conv_bufsiz; --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
