aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2023-03-10 13:52:28 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2023-03-10 13:52:44 -0500
commitd66bb048c3130c7b7a4876fc9050291f9e4cad2b (patch)
treed28ce5d139201bec389c88d6599ecd6570d0e19a /src/backend/commands
parentc45dc7ffbba2cb0bf180a0b9edadc22769143e7a (diff)
downloadpostgresql-d66bb048c3130c7b7a4876fc9050291f9e4cad2b.tar.gz
postgresql-d66bb048c3130c7b7a4876fc9050291f9e4cad2b.zip
Ensure COPY TO on an RLS-enabled table copies no more than it should.
The COPY documentation is quite clear that "COPY relation TO" copies rows from only the named table, not any inheritance children it may have. However, if you enabled row-level security on the table then this stopped being true, because the code forgot to apply the ONLY modifier in the "SELECT ... FROM relation" query that it constructs in order to allow RLS predicates to be attached. Fix that. Report and patch by Antonin Houska (comment adjustments and test case by me). Back-patch to all supported branches. Discussion: https://postgr.es/m/3472.1675251957@antos
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/copy.c5
-rw-r--r--src/backend/commands/copyto.c4
2 files changed, 6 insertions, 3 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index e34f583ea70..f3bbd91fe3e 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -244,11 +244,14 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
/*
* Build RangeVar for from clause, fully qualified based on the
- * relation which we have opened and locked.
+ * relation which we have opened and locked. Use "ONLY" so that
+ * COPY retrieves rows from only the target table not any
+ * inheritance children, the same as when RLS doesn't apply.
*/
from = makeRangeVar(get_namespace_name(RelationGetNamespace(rel)),
pstrdup(RelationGetRelationName(rel)),
-1);
+ from->inh = false; /* apply ONLY */
/* Build query */
select = makeNode(SelectStmt);
diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c
index 8043b4e9b1b..beea1ac687c 100644
--- a/src/backend/commands/copyto.c
+++ b/src/backend/commands/copyto.c
@@ -524,8 +524,8 @@ BeginCopyTo(ParseState *pstate,
/*
* With row-level security and a user using "COPY relation TO", we
* have to convert the "COPY relation TO" to a query-based COPY (eg:
- * "COPY (SELECT * FROM relation) TO"), to allow the rewriter to add
- * in any RLS clauses.
+ * "COPY (SELECT * FROM ONLY relation) TO"), to allow the rewriter to
+ * add in any RLS clauses.
*
* When this happens, we are passed in the relid of the originally
* found relation (which we have locked). As the planner will look up