Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
027e1eb
Harden our regex engine against integer overflow in size calculations.
tglsfdc May 11, 2026
412ed0d
Prevent buffer overrun in unicode_normalize().
tglsfdc May 11, 2026
e32edc3
Fix assorted places that need to use palloc_array().
tglsfdc May 11, 2026
2b94983
Add raw_connect and raw_connect_works to Cluster.pm
michaelpq May 11, 2026
e6604d9
Fix unbounded recursive handling of SSL/GSS in ProcessStartupPacket()
michaelpq May 11, 2026
0290e00
Unify src/common/'s definitions of MaxAllocSize.
tglsfdc May 11, 2026
81f991f
Guard against overflow in "left" fields of query_int and ltxtquery.
tglsfdc May 11, 2026
df6017c
Apply timingsafe_bcmp() in authentication paths
michaelpq May 11, 2026
fb8059f
Avoid passing unintended format codes to snprintf().
tglsfdc May 11, 2026
35498c2
Guard against unsafe conditions in usage of pg_strftime().
tglsfdc May 11, 2026
179a740
Check CREATE privilege on multirange type schema in CREATE TYPE.
nathan-bossart May 11, 2026
991f39d
Avoid overflow in size calculations in formatting.c.
nathan-bossart May 11, 2026
6c735a9
Prevent path traversal in pg_basebackup and pg_rewind
michaelpq May 11, 2026
f416ce0
Fix integer-overflow and alignment hazards in locale-related code.
tglsfdc May 11, 2026
95a926d
Fix integer overflow in array_agg(), when the array grows too large
hlinnaka May 11, 2026
678a06e
Mark PQfn() unsafe and fix overrun in frontend LO interface.
nathan-bossart May 11, 2026
493755b
refint: Fix SQL injection and buffer overruns.
nathan-bossart May 11, 2026
0e8d6de
Partally apply 37842f3dc6c
reshke May 23, 2026
466b330
Add timingsafe_bcmp(), for constant-time memory comparison
hlinnaka May 11, 2026
135476b
Make palloc_array() and friends safe against integer overflow.
tglsfdc May 11, 2026
74ac89e
Adapt cloubderry mock generator for pg_noinline function attribute
reshke May 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -19915,6 +19915,16 @@ fi
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_STRNLEN $ac_have_decl
_ACEOF
ac_fn_c_check_decl "$LINENO" "timingsafe_bcmp" "ac_cv_have_decl_timingsafe_bcmp" "$ac_includes_default"
if test "x$ac_cv_have_decl_timingsafe_bcmp" = xyes; then :
ac_have_decl=1
else
ac_have_decl=0
fi

cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_TIMINGSAFE_BCMP $ac_have_decl
_ACEOF


# We can't use AC_REPLACE_FUNCS to replace these functions, because it
Expand Down Expand Up @@ -20268,6 +20278,19 @@ esac

fi

ac_fn_c_check_func "$LINENO" "timingsafe_bcmp" "ac_cv_func_timingsafe_bcmp"
if test "x$ac_cv_func_timingsafe_bcmp" = xyes; then :
$as_echo "#define HAVE_TIMINGSAFE_BCMP 1" >>confdefs.h

else
case " $LIBOBJS " in
*" timingsafe_bcmp.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS timingsafe_bcmp.$ac_objext"
;;
esac

fi



if test "$enable_thread_safety" = yes; then
Expand Down
3 changes: 2 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2422,7 +2422,7 @@ AC_CHECK_DECLS(posix_fadvise, [], [], [#include <fcntl.h>])
]) # fi

AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>])
AC_CHECK_DECLS([strlcat, strlcpy, strnlen])
AC_CHECK_DECLS([strlcat, strlcpy, strnlen, timingsafe_bcmp])

# We can't use AC_REPLACE_FUNCS to replace these functions, because it
# won't handle deployment target restrictions on macOS
Expand Down Expand Up @@ -2471,6 +2471,7 @@ AC_REPLACE_FUNCS(m4_normalize([
strlcpy
strnlen
strtof
timingsafe_bcmp
]))

if test "$enable_thread_safety" = yes; then
Expand Down
60 changes: 48 additions & 12 deletions contrib/intarray/_int_bool.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,35 +436,66 @@ boolop(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(result);
}

/*
* Recursively fill the "left" fields of an ITEM array that represents
* a valid postfix tree.
*
* ptr: starting element of array
* pos: in/out argument, the array index this call is responsible to fill
*
* At exit, *pos has been decremented to point before the sub-tree whose
* top is the entry-time value of *pos.
*/
static void
findoprnd(ITEM *ptr, int32 *pos)
{
int32 mypos;

/* since this function recurses, it could be driven to stack overflow. */
check_stack_depth();

/* get the position this call is supposed to update */
mypos = *pos;
Assert(mypos >= 0);

/* in all cases, we should decrement *pos to advance over this item */
(*pos)--;

#ifdef BS_DEBUG
elog(DEBUG3, (ptr[*pos].type == OPR) ?
"%d %c" : "%d %d", *pos, ptr[*pos].val);
elog(DEBUG3, (ptr[mypos].type == OPR) ?
"%d %c" : "%d %d", mypos, ptr[mypos].val);
#endif
if (ptr[*pos].type == VAL)

if (ptr[mypos].type == VAL)
{
ptr[*pos].left = 0;
(*pos)--;
/* base case: a VAL has no operand, so just set its left to zero */
ptr[mypos].left = 0;
}
else if (ptr[*pos].val == (int32) '!')
else if (ptr[mypos].val == (int32) '!')
{
ptr[*pos].left = -1;
(*pos)--;
/* unary operator, likewise easy: operand is just before it */
ptr[mypos].left = -1;
/* recurse to scan operand */
findoprnd(ptr, pos);
}
else
{
ITEM *curitem = &ptr[*pos];
int32 tmp = *pos;
/* binary operator */
int32 delta;

(*pos)--;
/* recurse to scan right operand */
findoprnd(ptr, pos);
curitem->left = *pos - tmp;
/* we must fill left with offset to left operand's top */
/* abs(delta) < QUERYTYPEMAXITEMS, so it can't overflow ... */
delta = *pos - mypos;
/* ... but it might be too large to fit in the 16-bit left field */
Assert(delta < 0);
if (unlikely(delta < PG_INT16_MIN))
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("query_int expression is too complex")));
ptr[mypos].left = (int16) delta;
/* recurse to scan left operand */
findoprnd(ptr, pos);
}
}
Expand Down Expand Up @@ -514,6 +545,7 @@ bqarr_in(PG_FUNCTION_ARGS)
query->size = state.num;
ptr = GETQUERY(query);

/* fill the query array from the data makepol constructed */
for (i = state.num - 1; i >= 0; i--)
{
ptr[i].type = state.str->type;
Expand All @@ -523,8 +555,12 @@ bqarr_in(PG_FUNCTION_ARGS)
state.str = tmp;
}

/* now fill the "left" fields */
pos = query->size - 1;
findoprnd(ptr, &pos);
/* if successful, findoprnd should have scanned the whole array */
Assert(pos == -1);

#ifdef BS_DEBUG
initStringInfo(&pbuf);
for (i = 0; i < query->size; i++)
Expand Down
3 changes: 3 additions & 0 deletions contrib/intarray/expected/_int.out
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,9 @@ SELECT '1&(2&(4&(5|!6)))'::query_int;
1 & 2 & 4 & ( 5 | !6 )
(1 row)

SELECT (SELECT '0 | ' || string_agg(i::text, ' & ')
FROM generate_series(1, 17000) AS i)::query_int;
ERROR: query_int expression is too complex
CREATE TABLE test__int( a int[] );
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table.
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
Expand Down
2 changes: 2 additions & 0 deletions contrib/intarray/sql/_int.sql
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ SELECT '1&(2&(4&(5&6)))'::query_int;
SELECT '1&2&4&5&6'::query_int;
SELECT '1&(2&(4&(5|6)))'::query_int;
SELECT '1&(2&(4&(5|!6)))'::query_int;
SELECT (SELECT '0 | ' || string_agg(i::text, ' & ')
FROM generate_series(1, 17000) AS i)::query_int;


CREATE TABLE test__int( a int[] );
Expand Down
3 changes: 3 additions & 0 deletions contrib/ltree/expected/ltree.out
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,9 @@ SELECT 'tree.awdfg_qwerty'::ltree @ 'tree & aw_rw%*'::ltxtquery;
f
(1 row)

SELECT (SELECT 'a | ' || string_agg('b', ' & ')
FROM generate_series(1, 17000) AS i)::ltxtquery;
ERROR: ltxtquery is too large
--arrays
SELECT '{1.2.3}'::ltree[] @> '1.2.3.4';
?column?
Expand Down
51 changes: 41 additions & 10 deletions contrib/ltree/ltxtquery_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,31 +271,60 @@ makepol(QPRS_STATE *state)
return END;
}

/*
* Recursively fill the "left" fields of an ITEM array that represents
* a valid postfix tree.
*
* ptr: starting element of array
* pos: in/out argument, the array index this call is responsible to fill
*
* At exit, *pos has been incremented to point after the sub-tree whose
* top is the entry-time value of *pos.
*/
static void
findoprnd(ITEM *ptr, int32 *pos)
{
int32 mypos;

/* since this function recurses, it could be driven to stack overflow. */
check_stack_depth();

if (ptr[*pos].type == VAL || ptr[*pos].type == VALTRUE)
/* get the position this call is supposed to update */
mypos = *pos;

/* in all cases, we should increment *pos to advance over this item */
(*pos)++;

if (ptr[mypos].type == VAL || ptr[mypos].type == VALTRUE)
{
ptr[*pos].left = 0;
(*pos)++;
/* base case: a VAL has no operand, so just set its left to zero */
ptr[mypos].left = 0;
}
else if (ptr[*pos].val == (int32) '!')
else if (ptr[mypos].val == (int32) '!')
{
ptr[*pos].left = 1;
(*pos)++;
/* unary operator, likewise easy: operand is just after it */
ptr[mypos].left = 1;
/* recurse to scan operand */
findoprnd(ptr, pos);
}
else
{
ITEM *curitem = &ptr[*pos];
int32 tmp = *pos;
/* binary operator */
int32 delta;

(*pos)++;
/* recurse to scan right operand */
findoprnd(ptr, pos);
curitem->left = *pos - tmp;
/* we must fill left with offset to left operand's top */
/* delta can't overflow, see LTXTQUERY_TOO_BIG ... */
delta = *pos - mypos;
/* ... but it might be too large to fit in the 16-bit left field */
Assert(delta > 0);
if (unlikely(delta > PG_INT16_MAX))
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("ltxtquery is too large")));
ptr[mypos].left = (int16) delta;
/* recurse to scan left operand */
findoprnd(ptr, pos);
}
}
Expand Down Expand Up @@ -372,6 +401,8 @@ queryin(char *buf)
/* set left operand's position for every operator */
pos = 0;
findoprnd(ptr, &pos);
/* if successful, findoprnd should have scanned the whole array */
Assert(pos == state.num);

return query;
}
Expand Down
3 changes: 3 additions & 0 deletions contrib/ltree/sql/ltree.sql
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ SELECT 'tree.awdfg'::ltree @ 'tree & aWdfg@'::ltxtquery;
SELECT 'tree.awdfg_qwerty'::ltree @ 'tree & aw_qw%*'::ltxtquery;
SELECT 'tree.awdfg_qwerty'::ltree @ 'tree & aw_rw%*'::ltxtquery;

SELECT (SELECT 'a | ' || string_agg('b', ' & ')
FROM generate_series(1, 17000) AS i)::ltxtquery;

--arrays

SELECT '{1.2.3}'::ltree[] @> '1.2.3.4';
Expand Down
Loading
Loading