Re: pg_upgrade fails with non-standard ACL

From: Noah Misch <noah(at)leadboat(dot)com>
To: Anastasia Lubennikova <a(dot)lubennikova(at)postgrespro(dot)ru>
Cc: Arthur Zakirov <zaartur(at)gmail(dot)com>, Alvaro Herrera <alvherre(at)2ndquadrant(dot)com>, Michael Paquier <michael(at)paquier(dot)xyz>, Grigory Smolkin <g(dot)smolkin(at)postgrespro(dot)ru>, pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: pg_upgrade fails with non-standard ACL
Date: 2021-03-09 07:25:47
Message-ID: 20210309072547.GB2676992@rfd.leadboat.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Thu, Feb 11, 2021 at 08:16:30PM +0300, Anastasia Lubennikova wrote:
> On 28.01.2021 09:55, Noah Misch wrote:
> >On Wed, Jan 27, 2021 at 07:32:42PM +0300, Anastasia Lubennikova wrote:
> >>On 27.01.2021 14:21, Noah Misch wrote:
> >>>On Mon, Jan 25, 2021 at 10:14:43PM +0300, Anastasia Lubennikova wrote:
> >>>>1) Could you please clarify, what do you mean by REVOKE failures?
> >>>>
> >>>>I tried following example:
> >>>>
> >>>>Start 9.6 cluster.
> >>>>
> >>>>REVOKE ALL ON function pg_switch_xlog() FROM public;
> >>>>REVOKE ALL ON function pg_switch_xlog() FROM backup;
> >>>>
> >>>>The upgrade to the current master passes with and without patch.
> >>>>It seems that current implementation of pg_upgrade doesn't take into account
> >>>>revoke ACLs.
> >>>I think you can observe it by adding "revoke all on function
> >>>pg_stat_get_subscription from public;" to test_add_acl_to_catalog_objects.sql
> >>>and then rerunning your test script. pg_dump will reproduce that REVOKE,
> >>>which would fail if postgresql.org had removed that function. That's fine, so
> >>>long as a comment mentions the limitation.

I've now tested exactly that. It didn't cause a test script failure, because
pg_upgrade_ACL_test.sh runs "pg_upgrade --check" but does not run the final
pg_upgrade (without --check). The failure happens only without --check. I've
attached a modified version of your test script that reproduces the problem.
It uses a different function, timenow(), so the test does not depend on
test_rename_catalog_objects_v14. The attached script fails with this output:

===
Consult the last few lines of "pg_upgrade_dump_13325.log" for
the probable cause of the failure.
Failure, exiting
===

That log file contains:

===
command: "/tmp/workdir/postgresql_bin_test_new/bin/pg_dump" --host /home/nm/src/pg/backbranch/extra --port 50432 --username nm --schema-only --quote-all-identifiers --binary-upgrade --format=custom --file="pg_upgrade_dump_13325.custom" 'dbname=postgres' >> "pg_upgrade_dump_13325.log" 2>&1

command: "/tmp/workdir/postgresql_bin_test_new/bin/pg_restore" --host /home/nm/src/pg/backbranch/extra --port 50432 --username nm --clean --create --exit-on-error --verbose --dbname template1 "pg_upgrade_dump_13325.custom" >> "pg_upgrade_dump_13325.log" 2>&1
pg_restore: connecting to database for restore
pg_restore: dropping DATABASE PROPERTIES postgres
pg_restore: dropping DATABASE postgres
pg_restore: creating DATABASE "postgres"
pg_restore: connecting to new database "postgres"
pg_restore: creating COMMENT "DATABASE "postgres""
pg_restore: creating DATABASE PROPERTIES "postgres"
pg_restore: connecting to new database "postgres"
pg_restore: creating pg_largeobject "pg_largeobject"
pg_restore: creating ACL "pg_catalog.FUNCTION "timenow"()"
pg_restore: while PROCESSING TOC:
pg_restore: from TOC entry 3047; 0 0 ACL FUNCTION "timenow"() nm
pg_restore: error: could not execute query: ERROR: function pg_catalog.timenow() does not exist
Command was: REVOKE ALL ON FUNCTION "pg_catalog"."timenow"() FROM PUBLIC;
===

> >>In the updated patch, I implemented generation of both GRANT ALL and REVOKE
> >>ALL for problematic objects. If I understand it correctly, these calls will
> >>clean object's ACL completely. And I see no harm in doing this, because the
> >>objects don't exist in the new cluster anyway.

Here's fix_system_objects_ACL.sql with your v14 test script:

===
\connect postgres
GRANT ALL ON function pg_catalog.pg_stat_get_subscription(pg_catalog.oid) TO "backup" ;
REVOKE ALL ON function pg_catalog.pg_stat_get_subscription(pg_catalog.oid) FROM "backup" ;
GRANT ALL ON pg_catalog.pg_stat_subscription TO "backup" ;
REVOKE ALL ON pg_catalog.pg_stat_subscription FROM "backup" ;
GRANT ALL ON pg_catalog.pg_subscription TO "backup","test" ;
REVOKE ALL ON pg_catalog.pg_subscription FROM "backup","test" ;
GRANT ALL (subenabled) ON pg_catalog.pg_subscription TO "backup" ;
REVOKE ALL (subenabled) ON pg_catalog.pg_subscription FROM "backup" ;
===

Considering the REVOKE statements, those new GRANT statements have no effect.
To prevent the final pg_upgrade failure, fix_system_objects_ACL.sql would need
"GRANT ALL ON FUNCTION pg_catalog.pg_stat_get_subscription(pg_catalog.oid) TO
PUBLIC;". Alternately, again, I don't mind if this case continues to fail, so
long as a comment mentions the limitation. How would you like to proceed?

One other thing:

> diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c
> index 43fc297eb6..f2d593f574 100644
> --- a/src/bin/pg_upgrade/check.c
> +++ b/src/bin/pg_upgrade/check.c
...
> +check_for_changed_signatures(void)
> +{
...
> + /*
> + *
> + * AclInfo array is sorted by obj_ident. This allows us to compare
> + * AclInfo entries with the query result above efficiently.
> + */
> + for (aclnum = 0; aclnum < dbinfo->non_def_acl_arr.nacls; aclnum++)
> + {
> + AclInfo *aclinfo = &dbinfo->non_def_acl_arr.aclinfos[aclnum];
> + bool report = false;
> +
> + while (objnum < ntups)
> + {
> + int ret;
> +
> + ret = strcmp(aclinfo->obj_ident,
> + PQgetvalue(res, objnum, i_obj_ident));

I think this should check obj_type in addition to obj_ident. Otherwise, it
can't distinguish a relation from a type of the same name.

nm

Attachment Content-Type Size
pg_upgrade_ACL_test_e2e.sh application/x-sh 3.4 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Pavel Stehule 2021-03-09 07:26:18 Re: [PATCH] regexp_positions ( string text, pattern text, flags text ) → setof int4range[]
Previous Message tsunakawa.takay@fujitsu.com 2021-03-09 07:23:41 RE: [PoC] Non-volatile WAL buffer