From: | Kohei KaiGai <kaigai(at)kaigai(dot)gr(dot)jp> |
---|---|
To: | Noah Misch <noah(at)2ndquadrant(dot)com> |
Cc: | Kohei Kaigai <Kohei(dot)Kaigai(at)emea(dot)nec(dot)com>, Robert Haas <robert(dot)haas(at)enterprisedb(dot)com>, Stephen Frost <sfrost(at)snowman(dot)net>, Heikki Linnakangas <heikki(dot)linnakangas(at)enterprisedb(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: [v9.2] Fix leaky-view problem, part 2 |
Date: | 2011-07-08 08:03:16 |
Message-ID: | CADyhKSVRafXPv8kNWxNOWQnW1WkMTRdQUuep6V5mFcvehzHZNQ@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
2011/7/7 Noah Misch <noah(at)2ndquadrant(dot)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(dot)Kaigai(at)emea(dot)nec(dot)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 <kaigai(at)kaigai(dot)gr(dot)jp>
From | Date | Subject | |
---|---|---|---|
Next Message | Heikki Linnakangas | 2011-07-08 08:18:19 | Re: [v9.2] Fix leaky-view problem, part 2 |
Previous Message | mike beeper | 2011-07-08 07:51:37 | Re: [HACKERS] Creating temp tables inside read only transactions |