Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 24aef33

Browse files
committed
Cleanup of rewriter and planner handling of Query.hasRowSecurity flag.
Be sure to pull up the subquery's hasRowSecurity flag when flattening a subquery in pull_up_simple_subquery(). This isn't a bug today because we don't look at the hasRowSecurity flag during planning, but it could easily be a bug tomorrow. Likewise, make rewriteRuleAction() pull up the hasRowSecurity flag when absorbing RTEs from a rule action. This isn't a bug either, for the opposite reason: the flag should never be set yet. But again, it seems like good future proofing. Add a comment explaining why rewriteTargetView() should *not* set hasRowSecurity when adding stuff to securityQuals. Improve some nearby comments about securityQuals processing, and document that field more completely in parsenodes.h. Patch by me, analysis by Dean Rasheed. Discussion: <CAEZATCXZ8tb2DV6f=bkhsMV6u_gRcZ0CZBw2J-qU84RxSukZog@mail.gmail.com>
1 parent 530f806 commit 24aef33

File tree

3 files changed

+36
-8
lines changed

3 files changed

+36
-8
lines changed

src/backend/optimizer/prep/prepjointree.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,9 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
11871187
*/
11881188
parse->hasSubLinks |= subquery->hasSubLinks;
11891189

1190+
/* If subquery had any RLS conditions, now main query does too */
1191+
parse->hasRowSecurity |= subquery->hasRowSecurity;
1192+
11901193
/*
11911194
* subquery won't be pulled up if it hasAggs, hasWindowFuncs, or
11921195
* hasTargetSRFs, so no work needed on those flags

src/backend/rewrite/rewriteHandler.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,15 @@ rewriteRuleAction(Query *parsetree,
446446
}
447447
}
448448

449+
/*
450+
* Also, we might have absorbed some RTEs with RLS conditions into the
451+
* sub_action. If so, mark it as hasRowSecurity, whether or not those
452+
* RTEs will be referenced after we finish rewriting. (Note: currently
453+
* this is a no-op because RLS conditions aren't added till later, but it
454+
* seems like good future-proofing to do this anyway.)
455+
*/
456+
sub_action->hasRowSecurity |= parsetree->hasRowSecurity;
457+
449458
/*
450459
* Each rule action's jointree should be the main parsetree's jointree
451460
* plus that rule's jointree, but usually *without* the original rtindex
@@ -1835,10 +1844,10 @@ fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown)
18351844
}
18361845

18371846
/*
1838-
* Add the new security quals to the start of the RTE's list so
1839-
* that they get applied before any existing security quals (which
1840-
* might have come from a user-written security barrier view, and
1841-
* might contain malicious code).
1847+
* Add the new security barrier quals to the start of the RTE's
1848+
* list so that they get applied before any existing barrier quals
1849+
* (which would have come from a security-barrier view, and should
1850+
* get lower priority than RLS conditions on the table itself).
18421851
*/
18431852
rte->securityQuals = list_concat(securityQuals,
18441853
rte->securityQuals);
@@ -2957,9 +2966,9 @@ rewriteTargetView(Query *parsetree, Relation view)
29572966
* only adjust their varnos to reference the new target (just the same as
29582967
* we did with the view targetlist).
29592968
*
2960-
* Note that there is special-case handling for the quals of a security
2961-
* barrier view, since they need to be kept separate from any
2962-
* user-supplied quals, so these quals are kept on the new target RTE.
2969+
* If it's a security-barrier view, its WHERE quals must be applied before
2970+
* quals from the outer query, so we attach them to the RTE as security
2971+
* barrier quals rather than adding them to the main WHERE clause.
29632972
*
29642973
* For INSERT, the view's quals can be ignored in the main query.
29652974
*/
@@ -2980,12 +2989,21 @@ rewriteTargetView(Query *parsetree, Relation view)
29802989
if (RelationIsSecurityView(view))
29812990
{
29822991
/*
2992+
* The view's quals go in front of existing barrier quals: those
2993+
* would have come from an outer level of security-barrier view,
2994+
* and so must get evaluated later.
2995+
*
29832996
* Note: the parsetree has been mutated, so the new_rte pointer is
29842997
* stale and needs to be re-computed.
29852998
*/
29862999
new_rte = rt_fetch(new_rt_index, parsetree->rtable);
29873000
new_rte->securityQuals = lcons(viewqual, new_rte->securityQuals);
29883001

3002+
/*
3003+
* Do not set parsetree->hasRowSecurity, because these aren't RLS
3004+
* conditions (they aren't affected by enabling/disabling RLS).
3005+
*/
3006+
29893007
/*
29903008
* Make sure that the query is marked correctly if the added qual
29913009
* has sublinks.

src/include/nodes/parsenodes.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,13 @@ typedef struct XmlSerialize
775775
* FirstLowInvalidHeapAttributeNumber from column numbers before storing
776776
* them in these fields. A whole-row Var reference is represented by
777777
* setting the bit for InvalidAttrNumber.
778+
*
779+
* securityQuals is a list of security barrier quals (boolean expressions),
780+
* to be tested in the listed order before returning a row from the
781+
* relation. It is always NIL in parser output. Entries are added by the
782+
* rewriter to implement security-barrier views and/or row-level security.
783+
* Note that the planner turns each boolean expression into an implicitly
784+
* AND'ed sublist, as is its usual habit with qualification expressions.
778785
*--------------------
779786
*/
780787
typedef enum RTEKind
@@ -872,7 +879,7 @@ typedef struct RangeTblEntry
872879
Bitmapset *selectedCols; /* columns needing SELECT permission */
873880
Bitmapset *insertedCols; /* columns needing INSERT permission */
874881
Bitmapset *updatedCols; /* columns needing UPDATE permission */
875-
List *securityQuals; /* any security barrier quals to apply */
882+
List *securityQuals; /* security barrier quals to apply, if any */
876883
} RangeTblEntry;
877884

878885
/*

0 commit comments

Comments
 (0)