Repository navigation
Commit c69a74d
pg_dump: skip pg_init_privs entries for non-existent roles
Before commit 5342874, PostgreSQL did not record role dependencies
for pg_init_privs entries in pg_shdepend, meaning DROP ROLE could leave
behind ACL entries whose grantee or grantor OID no longer exists in
pg_authid. Cross-cluster restores can produce the same situation on
modern releases.
Dangling entries caused pg_dump to emit invalid SQL such as "GRANT ...
TO "87868"" with a numeric OID as role name, which fails on restore or
pg_upgrade. A dangling grantor is just as damaging but less visible: it
surfaces as SET SESSION AUTHORIZATION "87868" wrapping an otherwise
valid grant. Additionally, a column that was never explicitly granted
anything (its actual attacl stays NULL) but carries an all-dangling
pg_init_privs entry could produce a spurious "REVOKE ... FROM "87868""
naming the dangling OID, because the column-ACL query picks up a column
whenever it has any pg_init_privs row, regardless of whether attacl is
NULL. (The analogous scenario for a plain function with proacl NULL
cannot occur: pg_dump only considers a function for ACL output at all
when its actual ACL is non-NULL, independent of pg_init_privs.)
Fix by filtering each aclitem whose grantor or non-PUBLIC grantee OID
does not appear in pg_roles (used instead of pg_authid to support
non-superuser pg_dump). The filtering is applied server-side in the
queries that fetch pg_init_privs data (getAdditionalACLs and the
column-level ACL prepared statement), where the OID check is
authoritative. This avoids modifying the WHERE clauses in
getAggregates/getFuncs, preserving pg_dump performance on large schemas.
If all entries for an object are dangling the result is NULL and no ACL
is emitted, which is correct -- we cannot restore grants involving roles
that do not exist. Note this also means no
binary_upgrade_set_record_init_privs() block is emitted for the object,
so the upgraded cluster has no pg_init_privs row for it at all and
nothing recreates one. Its actual privileges are correct, but a later
pg_dump has no initial privileges to diff against and falls back to the
object-type default, re-emitting the GRANT and REVOKE commands the
extension's script already performs. For an extension whose script does
REVOKE ALL ON FUNCTION orphan_reset() FROM PUBLIC;
GRANT SELECT ON orphan_view TO PUBLIC;
a dump of the upgraded cluster carries both statements alongside CREATE
EXTENSION, where a dump of the same database with the extension freshly
installed carries CREATE EXTENSION alone. That is harmless on restore
but permanent, and it makes the extension's members look as though
someone had changed their privileges. Preserving the row would mean
inventing a grantor for the dangling entries, so dropping it is the
better of the two; without this fix the same case does not merely look
untidy, it fails the upgrade outright, emitting GRANT ... TO "16384"
inside the binary_upgrade_set_record_init_privs() block.
A new TAP test, 008_pg_dump_dangling_initprivs.pl, covers a dangling
grantee and a dangling grantor on a function, a column with a real grant
mixed with a dangling entry, a never-granted column with an all-dangling
entry, a legitimate all-digit role name that must not be mistaken for a
dangling OID, the PUBLIC grantee case in both directions, the same
dangling-grantee scenario on an aggregate (getAggregates is a separate
query from getFuncs), and a run under --binary-upgrade, which has its
own ACL-reconstruction path in dumpACL that a plain dump never
exercises. That run also asserts that no SET SESSION AUTHORIZATION names
a bare numeric OID, since a dangling grantor reaches the dump through
that line rather than through the GRANT itself, whose grantee may be
perfectly valid, so a GRANT/REVOKE-only check cannot see it. Each case
fails when the corresponding piece of the fix is reverted, and only
then. The test is registered in src/bin/pg_dump/meson.build; without
that it runs only under the make build, whose prove_check globs t/*.pl,
and never under meson, which is what CI uses.
Backpatched to 15 only. getAdditionalACLs() does not exist before v15
(it arrived in 0c9d844); v14's pg_dump instead LEFT JOINs
pg_init_privs in a dozen per-object queries. What makes this filter
cheap is that getAdditionalACLs() runs once per dump; v14 has no such
place, so the same expression would land in queries returning a row per
object, which is the shape that drew performance objections during
review. Since pg_upgrade runs the new cluster's pg_dump, an upgrade
from v14 is already covered by the newer copy; a v14 backpatch would
only help pg_dump run out of a v14 installation.
Author: Hüseyin Demir <huseyin.d3r@gmail.com>
Author: Rui Zhao <zhaorui126@gmail.com>
Reviewed-by: Rui Zhao <zhaorui126@gmail.com>
Discussion: https://postgr.es/m/19483-80de42dc4e62cfd6%40postgresql.org
Backpatch-through: 151 parent d733fca commit c69a74d
3 files changed
Lines changed: 269 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
103 | 103 | | |
104 | 104 | | |
105 | 105 | | |
| 106 | + | |
106 | 107 | | |
107 | 108 | | |
108 | 109 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
238 | 238 | | |
239 | 239 | | |
240 | 240 | | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
241 | 270 | | |
242 | 271 | | |
243 | 272 | | |
| |||
10719 | 10748 | | |
10720 | 10749 | | |
10721 | 10750 | | |
10722 | | - | |
10723 | | - | |
| 10751 | + | |
| 10752 | + | |
| 10753 | + | |
10724 | 10754 | | |
10725 | 10755 | | |
10726 | 10756 | | |
| |||
16861 | 16891 | | |
16862 | 16892 | | |
16863 | 16893 | | |
16864 | | - | |
| 16894 | + | |
| 16895 | + | |
16865 | 16896 | | |
16866 | 16897 | | |
16867 | 16898 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
0 commit comments