Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1whq3I-000RlX-1K for pgsql-hackers@arkaria.postgresql.org; Thu, 09 Jul 2026 14:48:36 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1whq3F-00DPOT-0H for pgsql-hackers@arkaria.postgresql.org; Thu, 09 Jul 2026 14:48:33 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1whq3E-00DPOJ-2B for pgsql-hackers@lists.postgresql.org; Thu, 09 Jul 2026 14:48:33 +0000 Received: from mail-yx1-xb132.google.com ([2607:f8b0:4864:20::b132]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1whq3D-00000000Khv-0wiB for pgsql-hackers@lists.postgresql.org; Thu, 09 Jul 2026 14:48:32 +0000 Received: by mail-yx1-xb132.google.com with SMTP id 956f58d0204a3-664ce3000e6so1972178d50.0 for ; Thu, 09 Jul 2026 07:48:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1783608511; cv=none; d=google.com; s=arc-20260327; b=VjgzS/wi2tmYuFJCqpiu+9agvsNEX3RUDLEIqaRd3V8VD8Fqdbqw8v3MPJyxyBVaSm CCosf8wjrMjfOsWoQbUMrm7c+mcmnNwfwlKYX6mvF6I1X1AJ5TeaAZB1Na6m2M/rIapB 4fZ7CAGy0yjgYB5qfj8u7HbrKs+qDUf9hqQF0o+NHq++LcMOVgD5koNXejtRuxg5pETo y0JXHUfA2v33g+/Gv1miXFVrCzbAlHy0y2WSqf7UJQi8FRRrBWu4OpCX2wgStuwJA/gB zcmbe1oHcG4ThYU0fqVsVgR0XXOmUeeLVfb10MDjzc68VCdr3A3a8IS44sIO2NDxapKK ql2g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=XbYi2Oav1yAbO39bRWea9qu6Q+BePcubnoGgXk+cX+0=; fh=KJqbGoqY250Tjp1IoJ4/nMPGgzk4wqj0kX2kDwZjgck=; b=VlMSqWt+bNbufef4/1JSySV6iz1TGHx2zSAIhCpC2ggFYCni67SWhiR5rByShsoaYQ PZps2Te4a7vg1SwyOdDWhdwqWEGdFA/K9cvY5ahJoA9x5Jo2eS1nosM4zMRsftwMr5/P xMifOiuX8GGu7kB9IbcIR+wrdhUIRxw8cSiDAlpMGfYiUk43vqUzs3PYwoXoGWZIhKvm ZUB87iv+tPDn4VE6ySZgF9mPuAj1rM7w409SzYE4dnllU0WhcL/+wbi7mHKgrWdUnbn/ R4cI0/8PfEvgcbqTHIevztFD/pSQgESn6IHpj3eyky1Hp3L/4d0axopRrDkOwCilnz8x WcIQ==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783608511; x=1784213311; darn=lists.postgresql.org; h=content-type:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:from:to:cc:subject:date:message-id:reply-to :content-type; bh=XbYi2Oav1yAbO39bRWea9qu6Q+BePcubnoGgXk+cX+0=; b=Am69Y/VF/lhoipU+BUROd6DJbkETcdkGFLsjrd3W9FXoo4Sj7rti6LUdqcr4c/5xKh 7N+Putn/RC4QFRXT9i/naGmeLb/pSfGTnjQgbx3hzNblj8zxhkuyj3g7B/Dr7pnLn4t4 p+3aqJeAR6ArhKry6oF3QeYjI/HFga4S82vi6pyM0RcJmKQbPUIgZR4znMtfCqx4sQpt Yn9+qN3AkkZ3ZD3fu7Jl7jR89KvKFQfRP3XP8MxYSCs3kaFBuP4BVxCMU+YJCsuganhs zJXuQQ9C3MH0ohDsWzLh0lQPV/iH+D8PC+x+GYdZHgyqci9Ku/OaeICuQk57sr5q9pBv 4Jgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783608511; x=1784213311; h=content-type:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to:content-type; bh=XbYi2Oav1yAbO39bRWea9qu6Q+BePcubnoGgXk+cX+0=; b=sinq8JKNm8cN9lTdSVXW3XQH7/fYfJ2tvcdsneIXseKchpx7ocZ/gQDPzozfIDfsB/ qfcnJyAfFOepgki9+TwD5AkmyBYdRAWVnVHCdgjbK1G9ccnbJ0+WCFc27LJWGFePlSkq ybEZg2MT/5GxBaRKALcy7Zu9U0s72meBHa/Z9skGOTUwzOLWUiwmhUkemmHs3VedVIKo 4ofdb5Mg2DBghyKJGSalaphZkoEWEGXjKplY3fAGMc9Avk6vaT7pGfvD/0eIQmBo0gNJ sQ/1Pb/Qr9JNdIa9F3jkdt/KupwyV2FKcZMyo+J3wq+g19bPqaTMHCCfFn2CLxk51U2N QuWw== X-Gm-Message-State: AOJu0YyDJQ5RyvWUodk/CdLBp9lsNu0XAZG6bZ7WikdqXRu+iJjyQprU ZZENw+32kjJMyblWUE4DKgRgVredGXCxNZIwEy4QvbAthCBPydlFN9kKGVqkqVzrl7oexYWc8oF sPQnN3aQNpeSlQEdW5d+PhnXiWvlfKGY= X-Gm-Gg: AfdE7clIGqU+WEBtIx5oGtPofC5YgAKRNSqPsTFARIeWiqoC5UiKg14EEvaMkzWRI2U 8q9+8v1JcvcNC12e+hCokJ394MLfpHP1BIiXWevV4yn06xP8ZJPPo7SHSQ4RM74OcGhTsoc7vAa JLGScmAcuiWeZNapaTsf7XstuH73mlbgemAS9xpuoi1NvNoefd6djv5C2QbCW9qn1RQW62NbyB9 3GEukuryP0ZKMVhNgdBSyxi7yRJbUZaWu1aoOZ6ysuCAueWyDk7fujsjDWz7DxPVJAhH/X1SDT7 KhvlaAM41t/FzhE2iOkmG4NycAMcqcgYcS/gUoA= X-Received: by 2002:a05:690e:138e:b0:667:b234:d5e7 with SMTP id 956f58d0204a3-667b234e726mr3966604d50.86.1783608510606; Thu, 09 Jul 2026 07:48:30 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Ayush Tiwari Date: Thu, 9 Jul 2026 20:18:19 +0530 X-Gm-Features: AUfX_mzLP0vCaJM5uyxtMVFFvs-ZzTUIPRWMthMdpXguUdiwZT5XJ2rkwdb7lnQ Message-ID: Subject: Re: REVOKE's CASCADE protection doesn't work with INHERITed table owners To: Jacob Champion Cc: PostgreSQL Hackers Content-Type: multipart/alternative; boundary="000000000000b173f206562eb7f2" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000b173f206562eb7f2 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi, On Thu, 9 Jul 2026 at 04:24, Jacob Champion wrote: > On Mon, Jul 6, 2026 at 4:03=E2=80=AFAM Ayush Tiwari > wrote: > > The first sentence is still "The grantee might still have some grant > options via another grantor," and I don't think adding "direct" would > have helped me understand this any better the first time I read it. > I'm definitely up for more bikeshedding, though, because I don't > really like what I have... > Fair. The part that tripped me up was actually the second sentence, "granted by any role on the chain", since the code isn't checking whether some role could grant them, but whether the grantee itself still holds them directly via another grantor. Maybe something like "if the grantee still holds a grant option directly through another grantor, that privilege's chain is intact"? No strong opinion though. > > On check_circularity() for [1]: I tried the same aclmask_direct() swap, > > but since it runs on every GRANT ... WITH GRANT OPTION, which > > pg_dump/restore replays, erroring there could make restore/pg_upgrade o= f > > an existing cluster (one already holding the [1] self-grant) fail. > > Well, I think the complaint in [1] is that dump/restore *already* > fails, no? Can you provide an example of a correct (or benignly > incorrect) dump that would start failing? > The already-failing case in [1] is the one where the membership has been revoked (REVOKE member FROM owner), which leaves a true orphan. But the self-grant gets created as soon as an inheriting member does the redundant WITH GRANT OPTION self-grant, and if the membership is still in place, that cluster dumps and restores fine today. CREATE ROLE owner_role; CREATE ROLE member_role LOGIN; GRANT owner_role TO member_role; -- membership kept CREATE TABLE t (i int); ALTER TABLE t OWNER TO owner_role; GRANT SELECT ON t TO member_role WITH GRANT OPTION; SET ROLE member_role; GRANT SELECT ON t TO member_role WITH GRANT OPTION; -- self-grant relacl =3D {owner_role=3DarwdDxtm/owner_role, member_role=3Dr*/owner_role, member_role=3Dr*/member_role} pg_dump emits "SET SESSION AUTHORIZATION member_role; GRANT SELECT ON t TO member_role WITH GRANT OPTION;". Restoring that into a fresh cluster works today, but with the check_circularity() change it fails with "grant options cannot be granted back to your own grantor". So it's not that [1] is fine today; it's that the fix also breaks a broader set of clusters that currently round-trip (membership still present), including via pg_upgrade. That's why I think the check_circularity() side needs a companion dump/restore change rather than going in on its own. > As an aside, I'm not sure if check_circularity() is correctly > preventing cycles independently of this issue, so that part may end up > spiraling a bit. > Agreed, I did not check that either. Regards, Ayush --000000000000b173f206562eb7f2 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

On Thu, 9 Jul 20= 26 at 04:24, Jacob Champion <jacob.champion@enterprisedb.com> wrote:
On Mon, Jul 6, 2026 at 4:03=E2=80=AF= AM Ayush Tiwari <ayushtiwari.slg01@gmail.com> wrote:

The first sentence is still "The grantee might still have some grant options via another grantor," and I don't think adding "direc= t" would
have helped me understand this any better the first time I read it.
I'm definitely up for more bikeshedding, though, because I don't really like what I have...

Fair. The part that tri= pped me up was actually the second sentence,
"granted by any role o= n the chain", since the code isn't checking whether
some role c= ould grant them, but whether the grantee itself still holds
them directl= y via another grantor. Maybe something like "if the grantee
still h= olds a grant option directly through another grantor, that
privilege'= ;s chain is intact"? No strong opinion though.
=C2=A0
> On check_circularity() for [1]: I tried the same aclmask_direct() swap= ,
> but since it runs on every GRANT ... WITH GRANT OPTION, which
> pg_dump/restore replays, erroring there could make restore/pg_upgrade = of
> an existing cluster (one already holding the [1] self-grant) fail.

Well, I think the complaint in [1] is that dump/restore *already*
fails, no? Can you provide an example of a correct (or benignly
incorrect) dump that would start failing?

The alre= ady-failing case in [1] is the one where the membership has
been revoked= (REVOKE member FROM owner), which leaves a true orphan.
But the self-gr= ant gets created as soon as an inheriting member does
the redundant WITH= GRANT OPTION self-grant, and if the membership is
still in place, that = cluster dumps and restores fine today.

=C2=A0 CREATE ROLE owner_role= ;
=C2=A0 CREATE ROLE member_role LOGIN;
=C2=A0 GRANT owner_role TO me= mber_role; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0-- membership kept
=C2=A0 C= REATE TABLE t (i int);
=C2=A0 ALTER TABLE t OWNER TO owner_role;
=C2= =A0 GRANT SELECT ON t TO member_role WITH GRANT OPTION;
=C2=A0 SET ROLE = member_role;
=C2=A0 GRANT SELECT ON t TO member_role WITH GRANT OPTION; = =C2=A0 -- self-grant

=C2=A0 relacl =3D {owner_role=3DarwdDxtm/owner_= role,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 member_role=3Dr*/owner_r= ole,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 member_role=3Dr*/member_r= ole}

pg_dump emits "SET SESSION AUTHORIZATION member_role; GRAN= T SELECT ON
t TO member_role WITH GRANT OPTION;". Restoring that in= to a fresh
cluster works today, but with the check_circularity() change = it fails
with "grant options cannot be granted back to your own gra= ntor".

So it's not that [1] is fine today; it's that th= e fix also breaks a
broader set of clusters that currently round-trip (m= embership still
present), including via pg_upgrade. That's why I thi= nk the
check_circularity() side needs a companion dump/restore change ra= ther
than going in on its own.
=C2=A0
As an aside, I'm not sure if check_circularity() is correctly
preventing cycles independently of this issue, so that part may end up
spiraling a bit.

Agreed, I did not check that eith= er.

Regards,
Ayush=C2=A0
--000000000000b173f206562eb7f2--