diff options
author | Noah Misch <noah@leadboat.com> | 2014-02-17 09:33:31 -0500 |
---|---|---|
committer | Noah Misch <noah@leadboat.com> | 2014-02-17 09:33:37 -0500 |
commit | 0b7026d964c79515c8df00b37ab41d550bcdcbde (patch) | |
tree | d7da8c1299e1168454b05be8f88897ea3ebfc221 /contrib/ltree/ltxtquery_io.c | |
parent | 6a10e57b0f79678243f42e2a6033723975aa8530 (diff) |
Predict integer overflow to avoid buffer overruns.
Several functions, mostly type input functions, calculated an allocation
size such that the calculation wrapped to a small positive value when
arguments implied a sufficiently-large requirement. Writes past the end
of the inadvertent small allocation followed shortly thereafter.
Coverity identified the path_in() vulnerability; code inspection led to
the rest. In passing, add check_stack_depth() to prevent stack overflow
in related functions.
Back-patch to 8.4 (all supported versions). The non-comment hstore
changes touch code that did not exist in 8.4, so that part stops at 9.0.
Noah Misch and Heikki Linnakangas, reviewed by Tom Lane.
Security: CVE-2014-0064
Diffstat (limited to 'contrib/ltree/ltxtquery_io.c')
-rw-r--r-- | contrib/ltree/ltxtquery_io.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/contrib/ltree/ltxtquery_io.c b/contrib/ltree/ltxtquery_io.c index 826f4e1c9dd..13ea58df3f5 100644 --- a/contrib/ltree/ltxtquery_io.c +++ b/contrib/ltree/ltxtquery_io.c @@ -9,6 +9,7 @@ #include "crc32.h" #include "ltree.h" +#include "miscadmin.h" PG_FUNCTION_INFO_V1(ltxtq_in); Datum ltxtq_in(PG_FUNCTION_ARGS); @@ -213,6 +214,9 @@ makepol(QPRS_STATE *state) int4 lenstack = 0; uint16 flag = 0; + /* since this function recurses, it could be driven to stack overflow */ + check_stack_depth(); + while ((type = gettoken_query(state, &val, &lenval, &strval, &flag)) != END) { switch (type) @@ -277,6 +281,9 @@ makepol(QPRS_STATE *state) static void findoprnd(ITEM *ptr, int4 *pos) { + /* since this function recurses, it could be driven to stack overflow. */ + check_stack_depth(); + if (ptr[*pos].type == VAL || ptr[*pos].type == VALTRUE) { ptr[*pos].left = 0; @@ -341,8 +348,12 @@ queryin(char *buf) errmsg("syntax error"), errdetail("Empty query."))); - /* make finish struct */ + if (LTXTQUERY_TOO_BIG(state.num, state.sumlen)) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("ltxtquery is too large"))); commonlen = COMPUTESIZE(state.num, state.sumlen); + query = (ltxtquery *) palloc(commonlen); SET_VARSIZE(query, commonlen); query->size = state.num; |