mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
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 <frevadiscor89@gmail.com> Author: Masahiko Sawada <sawada.mshk@gmail.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Backpatch-through: 14 Security: CVE-2026-14664
This commit is contained in:
committed by
Noah Misch
parent
3b2238fbe9
commit
7df2aa8efe
@@ -1648,23 +1648,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;
|
||||
|
||||
Reference in New Issue
Block a user