Skip to content

Commit

Permalink
fix possible plpgsql_check crash, disallow late pldbapi2 initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
okbob committed Sep 16, 2024
1 parent a3681e5 commit 4662cc6
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 55 deletions.
7 changes: 1 addition & 6 deletions expected/plpgsql_check_active.out
Original file line number Diff line number Diff line change
Expand Up @@ -9421,9 +9421,4 @@ $$ language plpgsql;
\c
-- should not to crash
select trace_test(3);
WARNING: late initialization of fmgr_plpgsql_cache
trace_test
------------
3
(1 row)

ERROR: too late initialization of fmgr_plpgsql_cache
7 changes: 1 addition & 6 deletions expected/plpgsql_check_active_1.out
Original file line number Diff line number Diff line change
Expand Up @@ -9423,9 +9423,4 @@ $$ language plpgsql;
\c
-- should not to crash
select trace_test(3);
WARNING: late initialization of fmgr_plpgsql_cache
trace_test
------------
3
(1 row)

ERROR: too late initialization of fmgr_plpgsql_cache
7 changes: 1 addition & 6 deletions expected/plpgsql_check_active_2.out
Original file line number Diff line number Diff line change
Expand Up @@ -9420,9 +9420,4 @@ $$ language plpgsql;
\c
-- should not to crash
select trace_test(3);
WARNING: late initialization of fmgr_plpgsql_cache
trace_test
------------
3
(1 row)

ERROR: too late initialization of fmgr_plpgsql_cache
7 changes: 1 addition & 6 deletions expected/plpgsql_check_active_3.out
Original file line number Diff line number Diff line change
Expand Up @@ -9421,9 +9421,4 @@ $$ language plpgsql;
\c
-- should not to crash
select trace_test(3);
WARNING: late initialization of fmgr_plpgsql_cache
trace_test
------------
3
(1 row)

ERROR: too late initialization of fmgr_plpgsql_cache
37 changes: 6 additions & 31 deletions src/pldbgapi2.c
Original file line number Diff line number Diff line change
Expand Up @@ -834,40 +834,15 @@ pldbgapi2_func_setup(PLpgSQL_execstate *estate, PLpgSQL_function *func)
* in expected order (usually when plpgsql_check is initialized
* inside function.
*/
if (!fcache_plpgsql)
if (!fcache_plpgsql ||
fcache_plpgsql->magic != FMGR_CACHE_MAGIC ||
!fcache_plpgsql->is_plpgsql)
{
ereport(WARNING,
(errmsg("late initialization of fmgr_plpgsql_cache"),
errhint("use \"load 'plpgsql_check'\" before you try to use pldbgapi2")));

/*
* Unfortunately, we have not access to fmgr context, so we should
* to use top memory context. This is permament leak, but only for
* few calls until fmgr hook will be correctly used.
*/
oldcxt = MemoryContextSwitchTo(TopMemoryContext);

fcache_plpgsql = palloc0(sizeof(fmgr_plpgsql_cache));

fcache_plpgsql->magic = FMGR_CACHE_MAGIC;

fcache_plpgsql->funcid = func->fn_oid;

fcache_plpgsql->is_plpgsql = true;
fcache_plpgsql->fn_mcxt = CurrentMemoryContext;
fcache_plpgsql->stmtid_stack = palloc_array(int, INITIAL_PLDBGAPI2_STMT_STACK_SIZE);
fcache_plpgsql->stmtid_stack_size = INITIAL_PLDBGAPI2_STMT_STACK_SIZE;
fcache_plpgsql->current_stmtid_stack_size = 0;

last_fmgr_plpgsql_cache = fcache_plpgsql;

MemoryContextSwitchTo(oldcxt);
ereport(ERROR,
(errmsg("too late initialization of fmgr_plpgsql_cache"),
errhint("Use \"load 'plpgsql_check'\" before you use plpgsql_check functionality.")));
}

Assert(fcache_plpgsql->magic == FMGR_CACHE_MAGIC);
Assert(fcache_plpgsql);
Assert(fcache_plpgsql->is_plpgsql);

#ifdef USE_ASSERT_CHECKING

if (fcache_plpgsql->funcid != PLpgSQLinlineFunc)
Expand Down

0 comments on commit 4662cc6

Please sign in to comment.