mirror of
https://git.postgresql.org/git/postgresql.git
synced 2026-02-12 09:27:04 +08:00
In an RLS query, we must ensure that security filter quals are evaluated before ordinary query quals, in case the latter contain "leaky" functions that could expose the contents of sensitive rows. The original implementation of RLS planning ensured this by pushing the scan of a secured table into a sub-query that it marked as a security-barrier view. Unfortunately this results in very inefficient plans in many cases, because the sub-query cannot be flattened and gets planned independently of the rest of the query. To fix, drop the use of sub-queries to enforce RLS qual order, and instead mark each qual (RestrictInfo) with a security_level field establishing its priority for evaluation. Quals must be evaluated in security_level order, except that "leakproof" quals can be allowed to go ahead of quals of lower security_level, if it's helpful to do so. This has to be enforced within the ordering of any one list of quals to be evaluated at a table scan node, and we also have to ensure that quals are not chosen for early evaluation (i.e., use as an index qual or TID scan qual) if they're not allowed to go ahead of other quals at the scan node. This is sufficient to fix the problem for RLS quals, since we only support RLS policies on simple tables and thus RLS quals will always exist at the table scan level only. Eventually these qual ordering rules should be enforced for join quals as well, which would permit improving planning for explicit security-barrier views; but that's a task for another patch. Note that FDWs would need to be aware of these rules --- and not, for example, send an insecure qual for remote execution --- but since we do not yet allow RLS policies on foreign tables, the case doesn't arise. This will need to be addressed before we can allow such policies. Patch by me, reviewed by Stephen Frost and Dean Rasheed. Discussion: https://postgr.es/m/8185.1477432701@sss.pgh.pa.us
47 lines
1.6 KiB
C
47 lines
1.6 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* restrictinfo.h
|
|
* prototypes for restrictinfo.c.
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/optimizer/restrictinfo.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef RESTRICTINFO_H
|
|
#define RESTRICTINFO_H
|
|
|
|
#include "nodes/relation.h"
|
|
|
|
|
|
/* Convenience macro for the common case of a valid-everywhere qual */
|
|
#define make_simple_restrictinfo(clause) \
|
|
make_restrictinfo(clause, true, false, false, 0, NULL, NULL, NULL)
|
|
|
|
extern RestrictInfo *make_restrictinfo(Expr *clause,
|
|
bool is_pushed_down,
|
|
bool outerjoin_delayed,
|
|
bool pseudoconstant,
|
|
Index security_level,
|
|
Relids required_relids,
|
|
Relids outer_relids,
|
|
Relids nullable_relids);
|
|
extern bool restriction_is_or_clause(RestrictInfo *restrictinfo);
|
|
extern bool restriction_is_securely_promotable(RestrictInfo *restrictinfo,
|
|
RelOptInfo *rel);
|
|
extern List *get_actual_clauses(List *restrictinfo_list);
|
|
extern List *extract_actual_clauses(List *restrictinfo_list,
|
|
bool pseudoconstant);
|
|
extern void extract_actual_join_clauses(List *restrictinfo_list,
|
|
List **joinquals,
|
|
List **otherquals);
|
|
extern bool join_clause_is_movable_to(RestrictInfo *rinfo, RelOptInfo *baserel);
|
|
extern bool join_clause_is_movable_into(RestrictInfo *rinfo,
|
|
Relids currentrelids,
|
|
Relids current_and_outer);
|
|
|
|
#endif /* RESTRICTINFO_H */
|