aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2018-07-04 09:26:19 +0200
committerPeter Eisentraut <peter_e@gmx.net>2018-07-13 10:41:40 +0200
commit3804e89bd0e94fb412d3eecb2113cc97e0f7310b (patch)
tree39ec8a13fa0c559eee23a58b0a7c6c0220213e96
parent39035a52894a419ae1b905adfdb0bad72ee19a36 (diff)
downloadpostgresql-3804e89bd0e94fb412d3eecb2113cc97e0f7310b.tar.gz
postgresql-3804e89bd0e94fb412d3eecb2113cc97e0f7310b.zip
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
-rw-r--r--doc/src/sgml/ref/create_procedure.sgml6
-rw-r--r--src/backend/commands/functioncmds.c9
-rw-r--r--src/pl/plpgsql/src/expected/plpgsql_transaction.out12
-rw-r--r--src/pl/plpgsql/src/sql/plpgsql_transaction.sql13
4 files changed, 40 insertions, 0 deletions
diff --git a/doc/src/sgml/ref/create_procedure.sgml b/doc/src/sgml/ref/create_procedure.sgml
index f3c3bb006cf..6c1de34b012 100644
--- a/doc/src/sgml/ref/create_procedure.sgml
+++ b/doc/src/sgml/ref/create_procedure.sgml
@@ -203,6 +203,12 @@ CREATE [ OR REPLACE ] PROCEDURE
conformance, but it is optional since, unlike in SQL, this feature
applies to all procedures not only external ones.
</para>
+
+ <para>
+ A <literal>SECURITY DEFINER</literal> procedure cannot execute
+ transaction control statements (for example, <command>COMMIT</command>
+ and <command>ROLLBACK</command>, depending on the language).
+ </para>
</listitem>
</varlistentry>
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 84daa19e064..68109bfda06 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -2246,6 +2246,15 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver
callcontext->atomic = true;
/*
+ * In security definer procedures, we can't allow transaction commands.
+ * StartTransaction() insists that the security context stack is empty,
+ * and AbortTransaction() resets the security context. This could be
+ * reorganized, but right now it doesn't work.
+ */
+ if (((Form_pg_proc )GETSTRUCT(tp))->prosecdef)
+ callcontext->atomic = true;
+
+ /*
* Expand named arguments, defaults, etc.
*/
fexpr->args = expand_function_arguments(fexpr->args, fexpr->funcresulttype, tp);
diff --git a/src/pl/plpgsql/src/expected/plpgsql_transaction.out b/src/pl/plpgsql/src/expected/plpgsql_transaction.out
index 274b2c6f170..0b5a039b89c 100644
--- a/src/pl/plpgsql/src/expected/plpgsql_transaction.out
+++ b/src/pl/plpgsql/src/expected/plpgsql_transaction.out
@@ -130,6 +130,18 @@ $$;
CALL transaction_test5();
ERROR: invalid transaction termination
CONTEXT: PL/pgSQL function transaction_test5() line 3 at COMMIT
+-- SECURITY DEFINER currently disallow transaction statements
+CREATE PROCEDURE transaction_test5b()
+LANGUAGE plpgsql
+SECURITY DEFINER
+AS $$
+BEGIN
+ COMMIT;
+END;
+$$;
+CALL transaction_test5b();
+ERROR: invalid transaction termination
+CONTEXT: PL/pgSQL function transaction_test5b() line 3 at COMMIT
TRUNCATE test1;
-- nested procedure calls
CREATE PROCEDURE transaction_test6(c text)
diff --git a/src/pl/plpgsql/src/sql/plpgsql_transaction.sql b/src/pl/plpgsql/src/sql/plpgsql_transaction.sql
index 1624aed6eca..236db9bf2bf 100644
--- a/src/pl/plpgsql/src/sql/plpgsql_transaction.sql
+++ b/src/pl/plpgsql/src/sql/plpgsql_transaction.sql
@@ -116,6 +116,19 @@ $$;
CALL transaction_test5();
+-- SECURITY DEFINER currently disallow transaction statements
+CREATE PROCEDURE transaction_test5b()
+LANGUAGE plpgsql
+SECURITY DEFINER
+AS $$
+BEGIN
+ COMMIT;
+END;
+$$;
+
+CALL transaction_test5b();
+
+
TRUNCATE test1;
-- nested procedure calls