From 79567e1aa864bcd3692546965d774285bc1fcc7c Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Mon, 19 Jul 2010 19:44:45 +0200
Subject: [PATCH] Don't segfault upon too deeply nested subtransactions.

Instead check the stack depth in AssignTransactionId() and refuse
deeper nesting in PushTransaction(). Both is checked as
AssignTransactionId might start from a relatively high stack level and
erroring out in PushTransaction gives a better error location.
---
 src/backend/access/transam/xact.c |   11 ++++++++++-
 src/include/access/xact.h         |    7 +++++++
 2 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 6ba6534..6a69355 100644
*** a/src/backend/access/transam/xact.c
--- b/src/backend/access/transam/xact.c
*************** AssignTransactionId(TransactionState s)
*** 410,417 ****
  	 * Ensure parent(s) have XIDs, so that a child always has an XID later
  	 * than its parent.
  	 */
! 	if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
  		AssignTransactionId(s->parent);
  
  	/*
  	 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
--- 410,419 ----
  	 * Ensure parent(s) have XIDs, so that a child always has an XID later
  	 * than its parent.
  	 */
! 	if (isSubXact && !TransactionIdIsValid(s->parent->transactionId)){
! 		check_stack_depth();
  		AssignTransactionId(s->parent);
+ 	}
  
  	/*
  	 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
*************** PushTransaction(void)
*** 4129,4134 ****
--- 4131,4143 ----
  	TransactionState p = CurrentTransactionState;
  	TransactionState s;
  
+ 	if(p->nestingLevel > XACT_MAX_NESTING){
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ 				 errmsg("cannot have more than %i nested subtransactions", XACT_MAX_NESTING)));
+ 	}
+ 
+ 
  	/*
  	 * We keep subtransaction state nodes in TopTransactionContext.
  	 */
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index 3bce72f..b654312 100644
*** a/src/include/access/xact.h
--- b/src/include/access/xact.h
***************
*** 28,33 ****
--- 28,40 ----
  #define XACT_REPEATABLE_READ	2
  #define XACT_SERIALIZABLE		3
  
+ /*
+  * too deep nesting causes stack depth problems and performance
+  * degradiations.
+  * This number is arbitrary.
+  */
+ #define XACT_MAX_NESTING		3000
+ 
  extern int	DefaultXactIsoLevel;
  extern int	XactIsoLevel;
  
-- 
1.7.2.rc1.10.gae32f

