~ubuntu-branches/ubuntu/vivid/postgresql-9.4/vivid-security

« back to all changes in this revision

Viewing changes to src/backend/regex/regcomp.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2015-10-08 15:36:31 UTC
  • mfrom: (1.2.3) (11.1.2 vivid-proposed)
  • Revision ID: package-import@ubuntu.com-20151008153631-dyiutwil2zjh9pxs
Tags: 9.4.5-0ubuntu0.15.04
* New upstream security/bug fix release: (LP: #1504132)
  - Guard against stack overflows in json parsing.
    If an application constructs PostgreSQL json or jsonb values from
    arbitrary user input, the application's users can reliably crash the
    PostgreSQL server, causing momentary denial of service.  (CVE-2015-5289)

  - Fix contrib/pgcrypto to detect and report too-short crypt() salts
    Certain invalid salt arguments crashed the server or disclosed a few
    bytes of server memory.  We have not ruled out the viability of attacks
    that arrange for presence of confidential information in the disclosed
    bytes, but they seem unlikely.  (CVE-2015-5288)

  - See release notes for details about other fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
 
35
35
#include "regex/regguts.h"
36
36
 
37
 
#include "miscadmin.h"                  /* needed by rcancelrequested() */
 
37
#include "miscadmin.h"                  /* needed by rcancelrequested/rstacktoodeep */
38
38
 
39
39
/*
40
40
 * forward declarations, up here so forward datatypes etc. are defined early
70
70
static void freelacons(struct subre *, int);
71
71
static void rfree(regex_t *);
72
72
static int      rcancelrequested(void);
 
73
static int      rstacktoodeep(void);
73
74
 
74
75
#ifdef REG_DEBUG
75
76
static void dump(regex_t *, FILE *);
152
153
#define COMPATIBLE      3                       /* compatible but not satisfied yet */
153
154
static int      combine(struct arc *, struct arc *);
154
155
static void fixempties(struct nfa *, FILE *);
155
 
static struct state *emptyreachable(struct state *, struct state *);
 
156
static struct state *emptyreachable(struct nfa *, struct state *, struct state *);
156
157
static void replaceempty(struct nfa *, struct state *, struct state *);
157
158
static void cleanup(struct nfa *);
158
159
static void markreachable(struct nfa *, struct state *, struct state *, struct state *);
228
229
        struct subre *tree;                     /* subexpression tree */
229
230
        struct subre *treechain;        /* all tree nodes allocated */
230
231
        struct subre *treefree;         /* any free tree nodes */
231
 
        int                     ntree;                  /* number of tree nodes */
 
232
        int                     ntree;                  /* number of tree nodes, plus one */
232
233
        struct cvec *cv;                        /* interface cvec */
233
234
        struct cvec *cv2;                       /* utility cvec */
234
235
        struct subre *lacons;           /* lookahead-constraint vector */
279
280
/* static function list */
280
281
static const struct fns functions = {
281
282
        rfree,                                          /* regfree insides */
282
 
        rcancelrequested                        /* check for cancel request */
 
283
        rcancelrequested,                       /* check for cancel request */
 
284
        rstacktoodeep                           /* check for stack getting dangerously deep */
283
285
};
284
286
 
285
287
 
568
570
         * splitting each such state into progress and no-progress states.
569
571
         */
570
572
 
571
 
        /* first, make a list of the states */
 
573
        /* first, make a list of the states reachable from pre and elsewhere */
572
574
        slist = NULL;
573
575
        for (a = pre->outs; a != NULL; a = a->outchain)
574
576
        {
575
577
                s = a->to;
576
578
                for (b = s->ins; b != NULL; b = b->inchain)
 
579
                {
577
580
                        if (b->from != pre)
578
581
                                break;
 
582
                }
 
583
 
 
584
                /*
 
585
                 * We want to mark states as being in the list already by having non
 
586
                 * NULL tmp fields, but we can't just store the old slist value in tmp
 
587
                 * because that doesn't work for the first such state.  Instead, the
 
588
                 * first list entry gets its own address in tmp.
 
589
                 */
579
590
                if (b != NULL && s->tmp == NULL)
580
591
                {
581
 
                        /*
582
 
                         * Must be split if not already in the list (fixes bugs 505048,
583
 
                         * 230589, 840258, 504785).
584
 
                         */
585
 
                        s->tmp = slist;
 
592
                        s->tmp = (slist != NULL) ? slist : s;
586
593
                        slist = s;
587
594
                }
588
595
        }
601
608
                                freearc(nfa, a);
602
609
                        }
603
610
                }
604
 
                s2 = s->tmp;
 
611
                s2 = (s->tmp != s) ? s->tmp : NULL;
605
612
                s->tmp = NULL;                  /* clean up while we're at it */
606
613
        }
607
614
}
942
949
                        NOERR();
943
950
                        assert(v->nextvalue > 0);
944
951
                        atom = subre(v, 'b', BACKR, lp, rp);
 
952
                        NOERR();
945
953
                        subno = v->nextvalue;
946
954
                        atom->subno = subno;
947
955
                        EMPTYARC(lp, rp);       /* temporarily, so there's something */
1076
1084
 
1077
1085
        /* break remaining subRE into x{...} and what follows */
1078
1086
        t = subre(v, '.', COMBINE(qprefer, atom->flags), lp, rp);
 
1087
        NOERR();
1079
1088
        t->left = atom;
1080
1089
        atomp = &t->left;
1081
1090
 
1084
1093
        /* split top into prefix and remaining */
1085
1094
        assert(top->op == '=' && top->left == NULL && top->right == NULL);
1086
1095
        top->left = subre(v, '=', top->flags, top->begin, lp);
 
1096
        NOERR();
1087
1097
        top->op = '.';
1088
1098
        top->right = t;
1089
1099
 
1618
1628
{
1619
1629
        struct subre *ret = v->treefree;
1620
1630
 
 
1631
        /*
 
1632
         * Checking for stack overflow here is sufficient to protect parse() and
 
1633
         * its recursive subroutines.
 
1634
         */
 
1635
        if (STACK_TOO_DEEP(v->re))
 
1636
        {
 
1637
                ERR(REG_ETOOBIG);
 
1638
                return NULL;
 
1639
        }
 
1640
 
1621
1641
        if (ret != NULL)
1622
1642
                v->treefree = ret->left;
1623
1643
        else
1930
1950
        return InterruptPending && (QueryCancelPending || ProcDiePending);
1931
1951
}
1932
1952
 
 
1953
/*
 
1954
 * rstacktoodeep - check for stack getting dangerously deep
 
1955
 *
 
1956
 * Return nonzero to fail the operation with error code REG_ETOOBIG,
 
1957
 * zero to keep going
 
1958
 *
 
1959
 * The current implementation is Postgres-specific.  If we ever get around
 
1960
 * to splitting the regex code out as a standalone library, there will need
 
1961
 * to be some API to let applications define a callback function for this.
 
1962
 */
 
1963
static int
 
1964
rstacktoodeep(void)
 
1965
{
 
1966
        return stack_is_too_deep();
 
1967
}
 
1968
 
1933
1969
#ifdef REG_DEBUG
1934
1970
 
1935
1971
/*