Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3884072

Browse files
committed
Prohibit transaction commands in security definer procedures
Starting and aborting transactions in security definer procedures doesn't work. StartTransaction() insists that the security context stack is empty, so this would currently cause a crash, and AbortTransaction() resets it. This could be made to work by reorganizing the code, but right now we just prohibit it. Reported-by: amul sul <sulamul@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/CAAJ_b96Gupt_LFL7uNyy3c50-wbhA68NUjiK5%3DrF6_w%3Dpq_T%3DQ%40mail.gmail.com
1 parent 1f4ec89 commit 3884072

File tree

4 files changed

+40
-0
lines changed

4 files changed

+40
-0
lines changed

doc/src/sgml/ref/create_procedure.sgml

+6
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,12 @@ CREATE [ OR REPLACE ] PROCEDURE
203203
conformance, but it is optional since, unlike in SQL, this feature
204204
applies to all procedures not only external ones.
205205
</para>
206+
207+
<para>
208+
A <literal>SECURITY DEFINER</literal> procedure cannot execute
209+
transaction control statements (for example, <command>COMMIT</command>
210+
and <command>ROLLBACK</command>, depending on the language).
211+
</para>
206212
</listitem>
207213
</varlistentry>
208214

src/backend/commands/functioncmds.c

+9
Original file line numberDiff line numberDiff line change
@@ -2245,6 +2245,15 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver
22452245
if (!heap_attisnull(tp, Anum_pg_proc_proconfig, NULL))
22462246
callcontext->atomic = true;
22472247

2248+
/*
2249+
* In security definer procedures, we can't allow transaction commands.
2250+
* StartTransaction() insists that the security context stack is empty,
2251+
* and AbortTransaction() resets the security context. This could be
2252+
* reorganized, but right now it doesn't work.
2253+
*/
2254+
if (((Form_pg_proc )GETSTRUCT(tp))->prosecdef)
2255+
callcontext->atomic = true;
2256+
22482257
/*
22492258
* Expand named arguments, defaults, etc.
22502259
*/

src/pl/plpgsql/src/expected/plpgsql_transaction.out

+12
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ $$;
130130
CALL transaction_test5();
131131
ERROR: invalid transaction termination
132132
CONTEXT: PL/pgSQL function transaction_test5() line 3 at COMMIT
133+
-- SECURITY DEFINER currently disallow transaction statements
134+
CREATE PROCEDURE transaction_test5b()
135+
LANGUAGE plpgsql
136+
SECURITY DEFINER
137+
AS $$
138+
BEGIN
139+
COMMIT;
140+
END;
141+
$$;
142+
CALL transaction_test5b();
143+
ERROR: invalid transaction termination
144+
CONTEXT: PL/pgSQL function transaction_test5b() line 3 at COMMIT
133145
TRUNCATE test1;
134146
-- nested procedure calls
135147
CREATE PROCEDURE transaction_test6(c text)

src/pl/plpgsql/src/sql/plpgsql_transaction.sql

+13
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,19 @@ $$;
116116
CALL transaction_test5();
117117

118118

119+
-- SECURITY DEFINER currently disallow transaction statements
120+
CREATE PROCEDURE transaction_test5b()
121+
LANGUAGE plpgsql
122+
SECURITY DEFINER
123+
AS $$
124+
BEGIN
125+
COMMIT;
126+
END;
127+
$$;
128+
129+
CALL transaction_test5b();
130+
131+
119132
TRUNCATE test1;
120133

121134
-- nested procedure calls

0 commit comments

Comments
 (0)