postgres.git / summary / log / commit / refs
commit 444ec169a7def141f9520c1111a31c8a5dda22ce
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: Wed Aug 24 17:01:40 2022 +0000
Defend against stack overrun in a few more places.
SplitToVariants() in the ispell code, lseg_inside_poly() in geo_ops.c,
and regex_selectivity_sub() in selectivity estimation could recurse
until stack overflow; fix by adding check_stack_depth() calls.
So could next() in the regex compiler, but that case is better fixed by
converting its tail recursion to a loop. (We probably get better code
that way too, since next() can now be inlined into its sole caller.)
There remains a reachable stack overrun in the Turkish stemmer, but
we'll need some advice from the Snowball people about how to fix that.
Per report from Egor Chindyaskin and Alexander Lakhin. These mistakes
are old, so back-patch to all supported branches.
Richard Guo and Tom Lane
Discussion: https://postgr.es/m/1661334672.728714027@f473.i.mail.ru
src/backend/regex/regc_lex.c | 5 +++--
src/backend/tsearch/spell.c | 4 ++++
src/backend/utils/adt/geo_ops.c | 3 +++
src/backend/utils/adt/like_support.c | 4 ++++
4 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/backend/regex/regc_lex.c b/src/backend/regex/regc_lex.c
index 7673dab76f4..826203e35d2 100644
--- a/src/backend/regex/regc_lex.c
+++ b/src/backend/regex/regc_lex.c
@@ -201,6 +201,8 @@ next(struct vars *v)
{
chr c;
+next_restart: /* loop here after eating a comment */
+
/* errors yield an infinite sequence of failures */
if (ISERR())
return 0; /* the error has set nexttype to EOS */
@@ -493,8 +495,7 @@ next(struct vars *v)
if (!ATEOS())
v->now++;
assert(v->nexttype == v->lasttype);
- return next(v);
- break;
+ goto next_restart;
case CHR('='): /* positive lookahead */
NOTE(REG_ULOOKAROUND);
RETV(LACON, LATYPE_AHEAD_POS);
diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c
index ebc89604ac2..961eb2709ca 100644
--- a/src/backend/tsearch/spell.c
+++ b/src/backend/tsearch/spell.c
@@ -63,6 +63,7 @@
#include "postgres.h"
#include "catalog/pg_collation.h"
+#include "miscadmin.h"
#include "tsearch/dicts/spell.h"
#include "tsearch/ts_locale.h"
#include "utils/memutils.h"
@@ -2399,6 +2400,9 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int
char *notprobed;
int compoundflag = 0;
+ /* since this function recurses, it could be driven to stack overflow */
+ check_stack_depth();
+
notprobed = (char *) palloc(wordlen);
memset(notprobed, 1, wordlen);
var = CopyVar(orig, 1);
diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c
index 9484dbc2273..bfd9ff6a36c 100644
--- a/src/backend/utils/adt/geo_ops.c
+++ b/src/backend/utils/adt/geo_ops.c
@@ -3919,6 +3919,9 @@ lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start)
bool res = true,
intersection = false;
+ /* since this function recurses, it could be driven to stack overflow */
+ check_stack_depth();
+
t.p[0] = *a;
t.p[1] = *b;
s.p[0] = poly->p[(start == 0) ? (poly->npts - 1) : (start - 1)];
diff --git a/src/backend/utils/adt/like_support.c b/src/backend/utils/adt/like_support.c
index 241e6f0f598..cba2d1376f0 100644
--- a/src/backend/utils/adt/like_support.c
+++ b/src/backend/utils/adt/like_support.c
@@ -44,6 +44,7 @@
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
#include "mb/pg_wchar.h"
+#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "nodes/supportnodes.h"
@@ -1338,6 +1339,9 @@ regex_selectivity_sub(const char *patt, int pattlen, bool case_insensitive)
int paren_pos = 0; /* dummy init to keep compiler quiet */
int pos;
+ /* since this function recurses, it could be driven to stack overflow */
+ check_stack_depth();
+
for (pos = 0; pos < pattlen; pos++)
{
if (patt[pos] == '(')
[parent: 04f1013be084]