aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorNoah Misch <noah@leadboat.com>2015-10-05 10:06:29 -0400
committerNoah Misch <noah@leadboat.com>2015-10-05 10:06:33 -0400
commit98f30d2e55d530ff47b2756b395a2048200a5ea4 (patch)
treecdf40b9c065524cf3173d9b17ad3c2a0359820f5 /src/backend
parent4d6752277e792386e54b036aee8f64ee4fa84cf1 (diff)
downloadpostgresql-98f30d2e55d530ff47b2756b395a2048200a5ea4.tar.gz
postgresql-98f30d2e55d530ff47b2756b395a2048200a5ea4.zip
Prevent stack overflow in json-related functions.
Sufficiently-deep recursion heretofore elicited a SIGSEGV. If an application constructs PostgreSQL json or jsonb values from arbitrary user input, application users could have exploited this to terminate all active database connections. That applies to 9.3, where the json parser adopted recursive descent, and later versions. Only row_to_json() and array_to_json() were at risk in 9.2, both in a non-security capacity. Back-patch to 9.2, where the json type was introduced. Oskari Saarenmaa, reviewed by Michael Paquier. Security: CVE-2015-5289
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/utils/adt/json.c6
-rw-r--r--src/backend/utils/adt/jsonb.c2
-rw-r--r--src/backend/utils/adt/jsonfuncs.c2
3 files changed, 10 insertions, 0 deletions
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index eefe93bc8ab..f394942bc35 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -490,6 +490,8 @@ parse_object(JsonLexContext *lex, JsonSemAction *sem)
json_struct_action oend = sem->object_end;
JsonTokenType tok;
+ check_stack_depth();
+
if (ostart != NULL)
(*ostart) (sem->semstate);
@@ -568,6 +570,8 @@ parse_array(JsonLexContext *lex, JsonSemAction *sem)
json_struct_action astart = sem->array_start;
json_struct_action aend = sem->array_end;
+ check_stack_depth();
+
if (astart != NULL)
(*astart) (sem->semstate);
@@ -1433,6 +1437,8 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
char *outputstr;
text *jsontext;
+ check_stack_depth();
+
/* callers are expected to ensure that null keys are not passed in */
Assert(!(key_scalar && is_null));
diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c
index f0f1651e9da..8fef35ea38a 100644
--- a/src/backend/utils/adt/jsonb.c
+++ b/src/backend/utils/adt/jsonb.c
@@ -712,6 +712,8 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
JsonbValue jb;
bool scalar_jsonb = false;
+ check_stack_depth();
+
if (is_null)
{
Assert(!key_scalar);
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c
index 01b6bb0a483..f33864e619d 100644
--- a/src/backend/utils/adt/jsonfuncs.c
+++ b/src/backend/utils/adt/jsonfuncs.c
@@ -3724,6 +3724,8 @@ setPath(JsonbIterator **it, Datum *path_elems,
JsonbValue *res = NULL;
int r;
+ check_stack_depth();
+
if (path_nulls[level])
elog(ERROR, "path element at the position %d is NULL", level + 1);