check_circularity does not prevent from creating circular grants

From: Kirill Reshke <reshkekirill(at)gmail(dot)com>
To: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: check_circularity does not prevent from creating circular grants
Date: 2026-08-10 07:03:04
Message-ID: CALdSSPiJUAO2VsWy3hvWghgThT=AwK5-HVrCp-+RYAiYiDjr4Q@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

HI!

I discovered a sequence of ddl which creates grant configuration,
unrestorable from pg_dump-pg_restore.

Simpliet repro will be:

CREATE ROLE r1 LOGIN;
CREATE ROLE r2 LOGIN;
CREATE ROLE r3;
GRANT r3 TO r2;
GRANT CREATE ON SCHEMA public TO r1;
SET ROLE r1;
CREATE VIEW v AS SELECT;
GRANT SELECT ON v TO r2 WITH GRANT OPTION; -- r2=r*/r1
GRANT SELECT ON v TO r3 WITH GRANT OPTION; -- r3=r*/r
SET ROLE r2;
GRANT SELECT ON v TO r2 WITH GRANT OPTION; -- r2=r*/r2 -- self
grant, already bad

Now, this is still pg_dump-pg_restore-able, but after we REVOKE r3
from r2 it wouldn't.

From my understanding, the reason is check_circularity tries to get
grantor's independently-derived privileges using aclmask function, but
this function also checks for has_privs_of_role in acl array.

This change fixes the problem for this exact case:
```
reshke(at)yezzey-cbdb-bench:~/pgpure$ cat p.pa
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index e2547d719ed..6f996cf2439 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -1281,7 +1281,7 @@ cc_restart:
aip = ACL_DAT(acl);
for (i = 0; i < num; i++)
{
- if (aip[i].ai_grantee == mod_aip->ai_grantee &&
+ if (has_privs_of_role(mod_aip->ai_grantee, aip[i].ai_grantee) &&
ACLITEM_GET_GOPTIONS(aip[i]) != ACL_NO_RIGHTS)
{
Acl *new_acl;
```

I dont know if this is correct for all possible scenarios thought

--
Best regards,
Kirill Reshke

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message torikoshia 2026-08-10 07:25:17 Re: Why is the LSN reported for pg_logical_emit_message() different from other decoded operations?
Previous Message Ashutosh Sharma 2026-08-10 07:00:14 Re: [PATCH] Release replication slot on error in SQL-callable slot functions