2011/7/7 Noah Misch <n...@2ndquadrant.com>:
> On Sun, Jul 03, 2011 at 11:41:47AM +0200, Kohei KaiGai wrote:
>> The simplified version of fix-leaky-view patch. The part of reloptions
>> for views got splitted out
>> into the part-0 patch, so it needs to be applied prior to this patch.
>> Rest of logic to prevent unexpected pushing down across security
>> barrier is not changed.
>>
>> Thanks,
>>
>> 2011/6/6 Kohei Kaigai <kohei.kai...@emea.nec.com>:
>> > This patch enables to fix up leaky-view problem using qualifiers that 
>> > reference only one-side of join-loop inside of view definition.
>> >
>> > The point of this scenario is criteria to distribute qualifiers of 
>> > scanning-plan distributed in distribute_qual_to_rels(). If and when a 
>> > qualifiers that reference only one-side of join-loop, the optimizer may 
>> > distribute this qualifier into inside of the join-loop, even if it goes 
>> > over the boundary of a subquery expanded from a view for row-level 
>> > security.
>> > This behavior allows us to reference whole of one-side of join-loop using 
>> > functions with side-effects.
>> > The solution is quite simple; it prohibits to distribute qualifiers over 
>> > the boundary of subquery, however, performance cost is unignorable, 
>> > because it also disables to utilize obviously indexable qualifiers such as 
>> > (id=123), so this patch requires users a hint whether a particular view is 
>> > for row-level security, or not.
>> >
>> > This patch newly adds "CREATE SECURITY VIEW" statement that marks a flag 
>> > to show this view was defined for row-level security purpose. This flag 
>> > shall be stored as reloptions.
>> > If this flag was set, the optimizer does not distribute qualifiers over 
>> > the boundary of subqueries expanded from security views, except for 
>> > obviously safe qualifiers.
>> > (Right now, we consider built-in indexable operators are safe, but it 
>> > might be arguable.)
>
> I took a moderately-detailed look at this patch.  This jumped out:
>
>> --- a/src/backend/optimizer/util/clauses.c
>> +++ b/src/backend/optimizer/util/clauses.c
>
>> +static bool
>> +contain_leakable_functions_walker(Node *node, void *context)
>> +{
>> +     if (node == NULL)
>> +             return false;
>> +
>> +     if (IsA(node, FuncExpr))
>> +     {
>> +             /*
>> +              * Right now, we have no way to distinguish safe functions with
>> +              * leakable ones, so, we treat all the function call possibly
>> +              * leakable.
>> +              */
>> +             return true;
>> +     }
>> +     else if (IsA(node, OpExpr))
>> +     {
>> +             OpExpr *expr = (OpExpr *) node;
>> +
>> +             /*
>> +              * Right now, we assume operators implemented by built-in 
>> functions
>> +              * are not leakable, so it does not need to prevent 
>> optimization.
>> +              */
>> +             set_opfuncid(expr);
>> +             if (get_func_lang(expr->opfuncid) != INTERNALlanguageId)
>> +                     return true;
>> +             /* else fall through to check args */
>> +     }
>
> Any user can do this:
>
>        CREATE OPERATOR !-! (PROCEDURE = int4in, RIGHTARG = cstring);
>        SELECT !-! 'foo';
>
As I mentioned at the source code comments, this ad-hoc assumption was
come from we have no way to distinguish a non-leaky function from others.
So, I definitely love the approach (2), because only trusted function creator
can determine whether it is possible leaky or not.

> Making a distinction based simply on the call being an operator vs. a function
> is a dead end.  I see these options:
>
> 1. The user defining a security view can be assumed to trust the operator 
> class
> members of indexes defined on the tables he references.  Keep track of which
> those are and treat only them as non-leakable.  This covers many interesting
> cases, but it's probably tricky to implement and/or costly at runtime.
>
It requires DBA massive amount of detailed knowledge about functions underlying
operators used in a view. I don't think it is a realistic assumption.

> 2. Add a pg_proc flag indicating whether the function is known leak-free.
> Simple, but tedious and perhaps error-prone.
>
+1

> 3. Trust operators owned by PGUID.  This is simple and probably covers the
> essential cases, but it's an ugly hack.
>
Some of built-in functions are also leaky. For example, int4div raise an error
when we try to divid a particular value by zero.

> 4. Trust nothing as leak-free.  Simple; performance will be unattractive.
>
-1, Because of performance perspective.

Thanks,
-- 
KaiGai Kohei <kai...@kaigai.gr.jp>

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to