postgres.git / summary / log / commit / refs

commit    137013f6084239bd824271c8c95beea496f4e2be
Author:   Nathan Bossart <nathan@postgresql.org>
Commit:   Noah Misch <noah@leadboat.com>
Date:     Mon May 11 12:13:50 2026 +0000

    Avoid overflow in size calculations in formatting.c.
    
    A few functions in this file were incautious about multiplying a
    possibly large integer by a factor more than 1 and then using it as
    an allocation size.  This is harmless on 64-bit systems where we'd
    compute a size exceeding MaxAllocSize and then fail, but on 32-bit
    systems we could overflow size_t, leading to an undersized
    allocation and buffer overrun.  To fix, use palloc_array() or
    mul_size() instead of handwritten multiplication.
    
    Reported-by: Sven Klemm <sven@tigerdata.com>
    Reported-by: Xint Code
    Author: Nathan Bossart <nathandbossart@gmail.com>
    Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
    Reviewed-by: Tatsuo Ishii <ishii@postgresql.org>
    Security: CVE-2026-6473
    Backpatch-through: 14


src/backend/utils/adt/formatting.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c index 1dbde70cd49..dc713c83f8c 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -4070,7 +4070,7 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt, bool is_interval, Oid collid) /* * Allocate workspace for result as C string */ - result = palloc((fmt_len * DCH_MAX_ITEM_SIZ) + 1); + result = palloc(mul_size(fmt_len, DCH_MAX_ITEM_SIZ) + 1); *result = '\0'; if (fmt_len > DCH_CACHE_SIZE) @@ -4081,7 +4081,7 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt, bool is_interval, Oid collid) */ incache = false; - format = (FormatNode *) palloc((fmt_len + 1) * sizeof(FormatNode)); + format = palloc_array(FormatNode, fmt_len + 1); parse_format(format, fmt_str, DCH_keywords, DCH_suff, DCH_index, DCH_FLAG, NULL); @@ -4553,7 +4553,7 @@ do_to_timestamp(text *date_txt, text *fmt, Oid collid, bool std, * Allocate new memory if format picture is bigger than static * cache and do not use cache (call parser always) */ - format = (FormatNode *) palloc((fmt_len + 1) * sizeof(FormatNode)); + format = palloc_array(FormatNode, fmt_len + 1); parse_format(format, fmt_str, DCH_keywords, DCH_suff, DCH_index, DCH_FLAG | (std ? STD_FLAG : 0), NULL); @@ -4993,7 +4993,7 @@ NUM_cache(int len, NUMDesc *Num, text *pars_str, bool *shouldFree) * Allocate new memory if format picture is bigger than static cache * and do not use cache (call parser always) */ - format = (FormatNode *) palloc((len + 1) * sizeof(FormatNode)); + format = palloc_array(FormatNode, len + 1); *shouldFree = true; [parent: 08c397b0234b]