Skip to content

Commit f25bed3

Browse files
committed
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/[email protected]
1 parent a73d6c8 commit f25bed3

File tree

4 files changed

+14
-2
lines changed

4 files changed

+14
-2
lines changed

src/backend/regex/regc_lex.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ next(struct vars *v)
201201
{
202202
chr c;
203203

204+
next_restart: /* loop here after eating a comment */
205+
204206
/* errors yield an infinite sequence of failures */
205207
if (ISERR())
206208
return 0; /* the error has set nexttype to EOS */
@@ -493,8 +495,7 @@ next(struct vars *v)
493495
if (!ATEOS())
494496
v->now++;
495497
assert(v->nexttype == v->lasttype);
496-
return next(v);
497-
break;
498+
goto next_restart;
498499
case CHR('='): /* positive lookahead */
499500
NOTE(REG_ULOOKAROUND);
500501
RETV(LACON, LATYPE_AHEAD_POS);

src/backend/tsearch/spell.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#include "postgres.h"
6464

6565
#include "catalog/pg_collation.h"
66+
#include "miscadmin.h"
6667
#include "tsearch/dicts/spell.h"
6768
#include "tsearch/ts_locale.h"
6869
#include "utils/memutils.h"
@@ -2400,6 +2401,9 @@ SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int
24002401
char *notprobed;
24012402
int compoundflag = 0;
24022403

2404+
/* since this function recurses, it could be driven to stack overflow */
2405+
check_stack_depth();
2406+
24032407
notprobed = (char *) palloc(wordlen);
24042408
memset(notprobed, 1, wordlen);
24052409
var = CopyVar(orig, 1);

src/backend/utils/adt/geo_ops.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3833,6 +3833,9 @@ lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start)
38333833
bool res = true,
38343834
intersection = false;
38353835

3836+
/* since this function recurses, it could be driven to stack overflow */
3837+
check_stack_depth();
3838+
38363839
t.p[0] = *a;
38373840
t.p[1] = *b;
38383841
s.p[0] = poly->p[(start == 0) ? (poly->npts - 1) : (start - 1)];

src/backend/utils/adt/like_support.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "catalog/pg_statistic.h"
4545
#include "catalog/pg_type.h"
4646
#include "mb/pg_wchar.h"
47+
#include "miscadmin.h"
4748
#include "nodes/makefuncs.h"
4849
#include "nodes/nodeFuncs.h"
4950
#include "nodes/supportnodes.h"
@@ -1364,6 +1365,9 @@ regex_selectivity_sub(const char *patt, int pattlen, bool case_insensitive)
13641365
int paren_pos = 0; /* dummy init to keep compiler quiet */
13651366
int pos;
13661367

1368+
/* since this function recurses, it could be driven to stack overflow */
1369+
check_stack_depth();
1370+
13671371
for (pos = 0; pos < pattlen; pos++)
13681372
{
13691373
if (patt[pos] == '(')

0 commit comments

Comments
 (0)