summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlvaro Herrera2023-11-08 17:44:54 +0000
committerAlvaro Herrera2023-11-08 17:44:54 +0000
commitb0f7dd915bca6243f3daf52a81b8d0682a38ee3b (patch)
treec1e5b01323f7a7c7ad3a19289e5297a1dc3b2564
parent76db9cb6368eb553ec334fe05e1258f2439bf07f (diff)
Check stack depth in new recursive functions
Commit b0e96f311985 introduced a bunch of recursive functions, but failed to make them check for stack depth. This can cause the backend to crash when operating on inheritance hierarchies several thousands deep. Protect the code by adding the missing stack depth checks. Reported-by: Alexander Lakhin <[email protected]> Discussion: https://postgr.es/m/[email protected]
-rw-r--r--src/backend/commands/tablecmds.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 416a98e7ce..e456ccd767 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -7630,6 +7630,9 @@ set_attnotnull(List **wqueue, Relation rel, AttrNumber attnum, bool recurse,
Form_pg_attribute attForm;
bool retval = false;
+ /* Guard against stack overflow due to overly deep inheritance tree. */
+ check_stack_depth();
+
tuple = SearchSysCacheCopyAttNum(RelationGetRelid(rel), attnum);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for attribute %d of relation %u",
@@ -7716,6 +7719,9 @@ ATExecSetNotNull(List **wqueue, Relation rel, char *conName, char *colName,
bool is_no_inherit = false;
List *ready = NIL;
+ /* Guard against stack overflow due to overly deep inheritance tree. */
+ check_stack_depth();
+
/*
* In cases of multiple inheritance, we might visit the same child more
* than once. In the topmost call, set up a list that we fill with all
@@ -9359,6 +9365,9 @@ ATAddCheckNNConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
ListCell *child;
ObjectAddress address = InvalidObjectAddress;
+ /* Guard against stack overflow due to overly deep inheritance tree. */
+ check_stack_depth();
+
/* At top level, permission check was done in ATPrepCmd, else do it */
if (recursing)
ATSimplePermissions(AT_AddConstraint, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
@@ -12428,6 +12437,9 @@ dropconstraint_internal(Relation rel, HeapTuple constraintTup, DropBehavior beha
return InvalidObjectAddress;
*readyRels = lappend_oid(*readyRels, RelationGetRelid(rel));
+ /* Guard against stack overflow due to overly deep inheritance tree. */
+ check_stack_depth();
+
/* At top level, permission check was done in ATPrepCmd, else do it */
if (recursing)
ATSimplePermissions(AT_DropConstraint, rel, ATT_TABLE | ATT_FOREIGN_TABLE);