postgres.git / summary / log / commit / refs

commit    f5157a9acc9d0c2b3d4a95b2967eae97451b671d
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Wed Aug 24 17:01:40 2022 +0000
First released in: 16.0, 10.23, 11.18, 12.13, 13.9, 14.6, 15.0

    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/selfuncs.c | 3 +++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/backend/regex/regc_lex.c b/src/backend/regex/regc_lex.c index abe39987e7d..bd637e121d1 100644 --- a/src/backend/regex/regc_lex.c +++ b/src/backend/regex/regc_lex.c @@ -278,6 +278,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 */ @@ -595,8 +597,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 34c91e049f3..bf63d7b7a0b 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" @@ -2394,6 +2395,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 da01fe6ba04..1819fda5559 100644 --- a/src/backend/utils/adt/geo_ops.c +++ b/src/backend/utils/adt/geo_ops.c @@ -3862,6 +3862,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/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 962bf075eea..471467af1cd 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -6022,6 +6022,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: 1a9c3ffd6428]