]> granicus.if.org Git - postgresql/commitdiff
Require execute permission on the trigger function for CREATE TRIGGER.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 23 Feb 2012 20:39:14 +0000 (15:39 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 23 Feb 2012 20:39:14 +0000 (15:39 -0500)
This check was overlooked when we added function execute permissions to the
system years ago.  For an ordinary trigger function it's not a big deal,
since trigger functions execute with the permissions of the table owner,
so they couldn't do anything the user issuing the CREATE TRIGGER couldn't
have done anyway.  However, if a trigger function is SECURITY DEFINER,
that is not the case.  The lack of checking would allow another user to
install it on his own table and then invoke it with, essentially, forged
input data; which the trigger function is unlikely to realize, so it might
do something undesirable, for instance insert false entries in an audit log
table.

Reported by Dinesh Kumar, patch by Robert Haas

Security: CVE-2012-0866

doc/src/sgml/ref/create_trigger.sgml
src/backend/commands/trigger.c

index 8d7574319f932d5d624e50144ea4973886bf1656..ecb1f56cbfe3f463f1eeefbf08103a20aededdac 100644 (file)
@@ -183,7 +183,8 @@ CREATE TRIGGER <replaceable class="PARAMETER">name</replaceable> { BEFORE | AFTE
 
   <para>
    To create a trigger on a table, the user must have the
-   <literal>TRIGGER</literal> privilege on the table.
+   <literal>TRIGGER</literal> privilege on the table.  The user must
+   also have <literal>EXECUTE</literal> privilege on the trigger function.
   </para>
 
   <para>
index e3c771a933f4d8d95c047d070c0f728458e38096..cadca5c01b0dad7f3f404e88d1c6a4ca22be3de4 100644 (file)
@@ -161,6 +161,10 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid, bool checkPermissions)
         * Find and validate the trigger function.
         */
        funcoid = LookupFuncName(stmt->funcname, 0, fargtypes, false);
+       aclresult = pg_proc_aclcheck(funcoid, GetUserId(), ACL_EXECUTE);
+       if (aclresult != ACLCHECK_OK)
+               aclcheck_error(aclresult, ACL_KIND_PROC,
+                                          NameListToString(stmt->funcname));
        funcrettype = get_func_rettype(funcoid);
        if (funcrettype != TRIGGEROID)
        {