mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-08-30 04:57:19 +02:00
pg_dump: avoid unsafe function calls in getPolicies().
getPolicies() had the same disease I fixed in other places in commite3fcbbd62
, i.e., it was calling pg_get_expr() for expressions on tables that we don't necessarily have lock on. To fix, restrict the query to only collect interesting rows, rather than doing the filtering on the client side. Back-patch of commit3e6e86abc
. That's been in v15/HEAD long enough to have some confidence about it, so now let's fix the problem in older branches. Discussion: https://postgr.es/m/2273648.1634764485@sss.pgh.pa.us Discussion: https://postgr.es/m/7d7eb6128f40401d81b3b7a898b6b4de@W2012-02.nidsa.loc Discussion: https://postgr.es/m/45c93d57-9973-248e-d2df-e02ca9af48d4@darold.net
This commit is contained in:
parent
e46e986bae
commit
a5b26aaafe
@ -3619,6 +3619,7 @@ void
|
|||||||
getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
|
getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
|
||||||
{
|
{
|
||||||
PQExpBuffer query;
|
PQExpBuffer query;
|
||||||
|
PQExpBuffer tbloids;
|
||||||
PGresult *res;
|
PGresult *res;
|
||||||
PolicyInfo *polinfo;
|
PolicyInfo *polinfo;
|
||||||
int i_oid;
|
int i_oid;
|
||||||
@ -3634,15 +3635,17 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
|
|||||||
j,
|
j,
|
||||||
ntups;
|
ntups;
|
||||||
|
|
||||||
|
/* No policies before 9.5 */
|
||||||
if (fout->remoteVersion < 90500)
|
if (fout->remoteVersion < 90500)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
query = createPQExpBuffer();
|
query = createPQExpBuffer();
|
||||||
|
tbloids = createPQExpBuffer();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First, check which tables have RLS enabled. We represent RLS being
|
* Identify tables of interest, and check which ones have RLS enabled.
|
||||||
* enabled on a table by creating a PolicyInfo object with null polname.
|
|
||||||
*/
|
*/
|
||||||
|
appendPQExpBufferChar(tbloids, '{');
|
||||||
for (i = 0; i < numTables; i++)
|
for (i = 0; i < numTables; i++)
|
||||||
{
|
{
|
||||||
TableInfo *tbinfo = &tblinfo[i];
|
TableInfo *tbinfo = &tblinfo[i];
|
||||||
@ -3651,9 +3654,23 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
|
|||||||
if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
|
if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* It can't have RLS or policies if it's not a table */
|
||||||
|
if (tbinfo->relkind != RELKIND_RELATION &&
|
||||||
|
tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Add it to the list of table OIDs to be probed below */
|
||||||
|
if (tbloids->len > 1) /* do we have more than the '{'? */
|
||||||
|
appendPQExpBufferChar(tbloids, ',');
|
||||||
|
appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
|
||||||
|
|
||||||
|
/* Is RLS enabled? (That's separate from whether it has policies) */
|
||||||
if (tbinfo->rowsec)
|
if (tbinfo->rowsec)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
* We represent RLS being enabled on a table by creating a
|
||||||
|
* PolicyInfo object with null polname.
|
||||||
|
*
|
||||||
* Note: use tableoid 0 so that this object won't be mistaken for
|
* Note: use tableoid 0 so that this object won't be mistaken for
|
||||||
* something that pg_depend entries apply to.
|
* something that pg_depend entries apply to.
|
||||||
*/
|
*/
|
||||||
@ -3673,15 +3690,18 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
|
|||||||
polinfo->polwithcheck = NULL;
|
polinfo->polwithcheck = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
appendPQExpBufferChar(tbloids, '}');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now, read all RLS policies, and create PolicyInfo objects for all those
|
* Now, read all RLS policies belonging to the tables of interest, and
|
||||||
* that are of interest.
|
* create PolicyInfo objects for them. (Note that we must filter the
|
||||||
|
* results server-side not locally, because we dare not apply pg_get_expr
|
||||||
|
* to tables we don't have lock on.)
|
||||||
*/
|
*/
|
||||||
pg_log_info("reading row-level security policies");
|
pg_log_info("reading row-level security policies");
|
||||||
|
|
||||||
printfPQExpBuffer(query,
|
printfPQExpBuffer(query,
|
||||||
"SELECT oid, tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
|
"SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
|
||||||
if (fout->remoteVersion >= 100000)
|
if (fout->remoteVersion >= 100000)
|
||||||
appendPQExpBuffer(query, "pol.polpermissive, ");
|
appendPQExpBuffer(query, "pol.polpermissive, ");
|
||||||
else
|
else
|
||||||
@ -3691,7 +3711,9 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
|
|||||||
" pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, "
|
" pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, "
|
||||||
"pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
|
"pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
|
||||||
"pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
|
"pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
|
||||||
"FROM pg_catalog.pg_policy pol");
|
"FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
|
||||||
|
"JOIN pg_catalog.pg_policy pol ON (src.tbloid = pol.polrelid)",
|
||||||
|
tbloids->data);
|
||||||
|
|
||||||
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
|
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
|
||||||
|
|
||||||
@ -3715,13 +3737,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
|
|||||||
Oid polrelid = atooid(PQgetvalue(res, j, i_polrelid));
|
Oid polrelid = atooid(PQgetvalue(res, j, i_polrelid));
|
||||||
TableInfo *tbinfo = findTableByOid(polrelid);
|
TableInfo *tbinfo = findTableByOid(polrelid);
|
||||||
|
|
||||||
/*
|
|
||||||
* Ignore row security on tables not to be dumped. (This will
|
|
||||||
* result in some harmless wasted slots in polinfo[].)
|
|
||||||
*/
|
|
||||||
if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
polinfo[j].dobj.objType = DO_POLICY;
|
polinfo[j].dobj.objType = DO_POLICY;
|
||||||
polinfo[j].dobj.catId.tableoid =
|
polinfo[j].dobj.catId.tableoid =
|
||||||
atooid(PQgetvalue(res, j, i_tableoid));
|
atooid(PQgetvalue(res, j, i_tableoid));
|
||||||
@ -3756,6 +3771,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
|
|||||||
PQclear(res);
|
PQclear(res);
|
||||||
|
|
||||||
destroyPQExpBuffer(query);
|
destroyPQExpBuffer(query);
|
||||||
|
destroyPQExpBuffer(tbloids);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user