]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Defend against stack overrun in a few more places.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 24 Aug 2022 17:01:40 +0000 (13:01 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 24 Aug 2022 17:01:40 +0000 (13:01 -0400)
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
src/backend/tsearch/spell.c
src/backend/utils/adt/geo_ops.c
src/backend/utils/adt/selfuncs.c

index abe39987e7d535729c493124e2b5b25971c1b22f..bd637e121d13d391e70faa3667655f0bbc5af7b2 100644 (file)
@@ -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);
index 34c91e049f3995cf55d8169fe2d8082e6c0b0be2..bf63d7b7a0bb5fe5a55e31ff7db8b933d0a2873a 100644 (file)
@@ -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);
index da01fe6ba04aa82427b2db6a134183dee7ffac6a..1819fda55591b2db181187c4777eecbbd2416614 100644 (file)
@@ -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)];
index 962bf075eea6be5f9d0743fcece4c514a3aff55c..471467af1cd47e3adfe27bfaac16191d810180c3 100644 (file)
@@ -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] == '(')