summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Misch2015-10-05 14:06:29 +0000
committerNoah Misch2015-10-05 14:06:36 +0000
commit0398e071adf5437bafaab7701dc46df55dceca76 (patch)
treed05906c3f3ea39a73c7f7f3537a9710d5939cfe2
parent188e081ef891d8590d2675b44331b8c450f616c4 (diff)
Prevent stack overflow in container-type functions.
A range type can name another range type as its subtype, and a record type can bear a column of another record type. Consequently, functions like range_cmp() and record_recv() are recursive. Functions at risk include operator family members and referents of pg_type regproc columns. Treat as recursive any such function that looks up and calls the same-purpose function for a record column type or the range subtype. Back-patch to 9.0 (all supported versions). An array type's element type is never itself an array type, so array functions are unaffected. Recursion depth proportional to array dimensionality, found in array_dim_to_jsonb(), is fine thanks to MAXDIM.
-rw-r--r--src/backend/utils/adt/rowtypes.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/backend/utils/adt/rowtypes.c b/src/backend/utils/adt/rowtypes.c
index fa2a1c4773e..00e361f016e 100644
--- a/src/backend/utils/adt/rowtypes.c
+++ b/src/backend/utils/adt/rowtypes.c
@@ -19,6 +19,7 @@
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "libpq/pqformat.h"
+#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/typcache.h"
@@ -88,6 +89,8 @@ record_in(PG_FUNCTION_ARGS)
bool *nulls;
StringInfoData buf;
+ check_stack_depth(); /* recurses for record-type columns */
+
/*
* Use the passed type unless it's RECORD; we can't support input of
* anonymous types, mainly because there's no good way to figure out which
@@ -310,6 +313,8 @@ record_out(PG_FUNCTION_ARGS)
bool *nulls;
StringInfoData buf;
+ check_stack_depth(); /* recurses for record-type columns */
+
/* Extract type info from the tuple itself */
tupType = HeapTupleHeaderGetTypeId(rec);
tupTypmod = HeapTupleHeaderGetTypMod(rec);
@@ -477,6 +482,8 @@ record_recv(PG_FUNCTION_ARGS)
Datum *values;
bool *nulls;
+ check_stack_depth(); /* recurses for record-type columns */
+
/*
* Use the passed type unless it's RECORD; we can't support input of
* anonymous types, mainly because there's no good way to figure out which
@@ -667,6 +674,8 @@ record_send(PG_FUNCTION_ARGS)
bool *nulls;
StringInfoData buf;
+ check_stack_depth(); /* recurses for record-type columns */
+
/* Extract type info from the tuple itself */
tupType = HeapTupleHeaderGetTypeId(rec);
tupTypmod = HeapTupleHeaderGetTypMod(rec);
@@ -826,6 +835,8 @@ record_cmp(FunctionCallInfo fcinfo)
int i2;
int j;
+ check_stack_depth(); /* recurses for record-type columns */
+
/* Extract type info from the tuples */
tupType1 = HeapTupleHeaderGetTypeId(record1);
tupTypmod1 = HeapTupleHeaderGetTypMod(record1);
@@ -1052,6 +1063,8 @@ record_eq(PG_FUNCTION_ARGS)
int i2;
int j;
+ check_stack_depth(); /* recurses for record-type columns */
+
/* Extract type info from the tuples */
tupType1 = HeapTupleHeaderGetTypeId(record1);
tupTypmod1 = HeapTupleHeaderGetTypMod(record1);