diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/access/transam/xact.c | 13 | ||||
-rw-r--r-- | src/backend/commands/portalcmds.c | 5 | ||||
-rw-r--r-- | src/backend/commands/trigger.c | 12 |
3 files changed, 24 insertions, 6 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index af6afcebb13..03c553e7eaa 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -2094,9 +2094,10 @@ CommitTransaction(void) /* * Do pre-commit processing that involves calling user-defined code, such - * as triggers. Since closing cursors could queue trigger actions, - * triggers could open cursors, etc, we have to keep looping until there's - * nothing left to do. + * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an + * action that would run here, because that would bypass the sandbox. + * Since closing cursors could queue trigger actions, triggers could open + * cursors, etc, we have to keep looping until there's nothing left to do. */ for (;;) { @@ -2114,9 +2115,6 @@ CommitTransaction(void) break; } - CallXactCallbacks(is_parallel_worker ? XACT_EVENT_PARALLEL_PRE_COMMIT - : XACT_EVENT_PRE_COMMIT); - /* * The remaining actions cannot call any user-defined code, so it's safe * to start shutting down within-transaction services. But note that most @@ -2124,6 +2122,9 @@ CommitTransaction(void) * the transaction-abort path. */ + CallXactCallbacks(is_parallel_worker ? XACT_EVENT_PARALLEL_PRE_COMMIT + : XACT_EVENT_PRE_COMMIT); + /* If we might have parallel workers, clean them up now. */ if (IsInParallelMode()) AtEOXact_Parallel(true); diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c index e4b7483e321..0b64204975d 100644 --- a/src/backend/commands/portalcmds.c +++ b/src/backend/commands/portalcmds.c @@ -27,6 +27,7 @@ #include "commands/portalcmds.h" #include "executor/executor.h" #include "executor/tstoreReceiver.h" +#include "miscadmin.h" #include "rewrite/rewriteHandler.h" #include "tcop/pquery.h" #include "tcop/tcopprot.h" @@ -65,6 +66,10 @@ PerformCursorOpen(ParseState *pstate, DeclareCursorStmt *cstmt, ParamListInfo pa */ if (!(cstmt->options & CURSOR_OPT_HOLD)) RequireTransactionBlock(isTopLevel, "DECLARE CURSOR"); + else if (InSecurityRestrictedOperation()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("cannot create a cursor WITH HOLD within security-restricted operation"))); /* * Parse analysis was done already, but we still have to run the rule diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 092ac1646de..e1f3472eca9 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -4021,6 +4021,7 @@ afterTriggerMarkEvents(AfterTriggerEventList *events, bool immediate_only) { bool found = false; + bool deferred_found = false; AfterTriggerEvent event; AfterTriggerEventChunk *chunk; @@ -4056,6 +4057,7 @@ afterTriggerMarkEvents(AfterTriggerEventList *events, */ if (defer_it && move_list != NULL) { + deferred_found = true; /* add it to move_list */ afterTriggerAddEvent(move_list, event, evtshared); /* mark original copy "done" so we don't do it again */ @@ -4063,6 +4065,16 @@ afterTriggerMarkEvents(AfterTriggerEventList *events, } } + /* + * We could allow deferred triggers if, before the end of the + * security-restricted operation, we were to verify that a SET CONSTRAINTS + * ... IMMEDIATE has fired all such triggers. For now, don't bother. + */ + if (deferred_found && InSecurityRestrictedOperation()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("cannot fire deferred trigger within security-restricted operation"))); + return found; } |