Skip to content

Commit 3b06bdd

Browse files
committed
Complete NULL guards for exec_state_call_stack in iterative_exec.c
The previous fix (68f12ee) only protected 2 of 9 unsafe exec_state_call_stack dereferences. This commit adds NULL guards to the remaining 7 sites that can crash when exec_state_call_stack is NULL during INSERT EXEC SPI execution. Protected functions/locations: 1. record_error_state() - guard at top 2. is_error_raising_batch() - guard at top 3. is_xact_abort_on_error() - guard at top 4. abort_transaction() line ~1159 - guard || right-hand side 5. abort_execution() lines ~1207, ~1210 - guard || and direct access 6. exec_stmt_iterative() lines ~1714-1718 - guard error_data block 7. exec_stmt_iterative() line ~1783 - guard condition with || NULL check 8. set_exec_error_data() - guard at top 9. reset_exec_error_data() - guard at top The exec_state_call_stack can be NULL during INSERT EXEC because the SPI execution path doesn't always have a full PL/tsql call stack established. Without these guards, any error during INSERT EXEC would cause a SIGSEGV.
1 parent 68f12ee commit 3b06bdd

File tree

1 file changed

+29
-8
lines changed

1 file changed

+29
-8
lines changed

contrib/babelfishpg_tsql/src/iterative_exec.c

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,9 @@ static
10831083
void
10841084
record_error_state(PLtsql_execstate *estate)
10851085
{
1086+
if (exec_state_call_stack == NULL)
1087+
return; /* parallel worker or unexpected context — skip */
1088+
10861089
if (exec_state_call_stack->error_data.error_estate == NULL)
10871090
{
10881091
exec_state_call_stack->error_data.error_estate = estate;
@@ -1103,6 +1106,9 @@ static
11031106
bool
11041107
is_error_raising_batch(PLtsql_execstate *estate)
11051108
{
1109+
if (exec_state_call_stack == NULL)
1110+
return false; /* parallel worker or unexpected context */
1111+
11061112
if (exec_state_call_stack->error_data.error_estate == estate)
11071113
return true;
11081114
return false;
@@ -1112,6 +1118,9 @@ static
11121118
bool
11131119
is_xact_abort_on_error(PLtsql_execstate *estate)
11141120
{
1121+
if (exec_state_call_stack == NULL)
1122+
return false; /* parallel worker or unexpected context */
1123+
11151124
if (exec_state_call_stack->error_data.xact_abort_on)
11161125
return true;
11171126
return false;
@@ -1150,7 +1159,8 @@ abort_transaction(PLtsql_execstate *estate, ErrorData *edata, uint8_t override_f
11501159
* If error is raised inside trigger execution then default behaviour is
11511160
* to rollback the transaction.
11521161
*/
1153-
if (is_part_of_pltsql_trigger(estate) || exec_state_call_stack->error_data.trigger_error)
1162+
if (is_part_of_pltsql_trigger(estate) ||
1163+
(exec_state_call_stack != NULL && exec_state_call_stack->error_data.trigger_error))
11541164
return true;
11551165

11561166
/* Transaction count mismatch error inside try catch block */
@@ -1197,10 +1207,11 @@ abort_execution(PLtsql_execstate *estate, ErrorData *edata, bool *terminate_batc
11971207
}
11981208

11991209
/* If any error inside trigger execution. */
1200-
if (is_part_of_pltsql_trigger(estate) || exec_state_call_stack->error_data.trigger_error)
1210+
if (is_part_of_pltsql_trigger(estate) ||
1211+
(exec_state_call_stack != NULL && exec_state_call_stack->error_data.trigger_error))
12011212
return true;
12021213

1203-
if (exec_state_call_stack->error_data.rethrow_error)
1214+
if (exec_state_call_stack != NULL && exec_state_call_stack->error_data.rethrow_error)
12041215
return true;
12051216

12061217
/* Any error inside try catch block */
@@ -1700,10 +1711,13 @@ exec_stmt_iterative(PLtsql_execstate *estate, ExecCodes *exec_codes, ExecConfig_
17001711
* is accessible inside the CATCH block.
17011712
*/
17021713
estate->cur_error->error = restore_ctx_partial1(estate);
1703-
estate->cur_error->procedure = exec_state_call_stack->error_data.error_procedure;
1704-
estate->cur_error->number = exec_state_call_stack->error_data.error_number;
1705-
estate->cur_error->severity = exec_state_call_stack->error_data.error_severity;
1706-
estate->cur_error->state = exec_state_call_stack->error_data.error_state;
1714+
if (exec_state_call_stack != NULL)
1715+
{
1716+
estate->cur_error->procedure = exec_state_call_stack->error_data.error_procedure;
1717+
estate->cur_error->number = exec_state_call_stack->error_data.error_number;
1718+
estate->cur_error->severity = exec_state_call_stack->error_data.error_severity;
1719+
estate->cur_error->state = exec_state_call_stack->error_data.error_state;
1720+
}
17071721

17081722
/* Goto error handling blocks */
17091723
*pc = err_handler_pc - 1; /* same as how goto handles PC */
@@ -1766,7 +1780,8 @@ exec_stmt_iterative(PLtsql_execstate *estate, ExecCodes *exec_codes, ExecConfig_
17661780
if (!is_seterror_on(stmt) &&
17671781
!is_control_command(stmt) &&
17681782
!is_batch_command(stmt) &&
1769-
exec_state_call_stack->error_data.error_estate == NULL)
1783+
(exec_state_call_stack == NULL ||
1784+
exec_state_call_stack->error_data.error_estate == NULL))
17701785
exec_set_error(estate, 0, 0, false /* error_mapping_failed */ );
17711786

17721787
/*
@@ -2085,6 +2100,9 @@ static
20852100
void
20862101
set_exec_error_data(char *procedure, int number, int severity, int state, bool rethrow)
20872102
{
2103+
if (exec_state_call_stack == NULL)
2104+
return; /* parallel worker — cannot record error data */
2105+
20882106
exec_state_call_stack->error_data.rethrow_error = rethrow;
20892107
exec_state_call_stack->error_data.error_procedure = procedure;
20902108
exec_state_call_stack->error_data.error_number = number;
@@ -2096,6 +2114,9 @@ static
20962114
void
20972115
reset_exec_error_data(PLtsql_execstate *estate)
20982116
{
2117+
if (exec_state_call_stack == NULL)
2118+
return; /* parallel worker — nothing to reset */
2119+
20992120
exec_state_call_stack->error_data.xact_abort_on = false;
21002121
exec_state_call_stack->error_data.rethrow_error = false;
21012122
if (estate->trigdata == NULL && estate->evtrigdata == NULL)

0 commit comments

Comments
 (0)