BUG #19097: System catalog modifications are allowed by alter

Started by PG Bug reporting form6 months ago5 messagesbugs
Jump to latest
#1PG Bug reporting form
noreply@postgresql.org

The following bug has been logged on the website:

Bug reference: 19097
Logged by: RekGRpth
Email address: rekgrpth@gmail.com
PostgreSQL version: 18.0
Operating system: docker alpine
Description:

```sql
create table pg_catalog.t (i int);
ERROR: permission denied to create "pg_catalog.t"
DETAIL: System catalog modifications are currently disallowed.

create table t (i int);
CREATE TABLE

alter table t set schema pg_catalog;
ALTER TABLE

\dS+ t
Table "pg_catalog.t"
Column | Type | Collation | Nullable | Default | Storage | Compression |
Stats target | Description
--------+---------+-----------+----------+---------+---------+-------------+--------------+-------------
i | integer | | | | plain | |
|
Replica Identity: NOTHING
Access method: heap

drop table pg_catalog.t;
DROP TABLE
```

#2Kirill Reshke
reshkekirill@gmail.com
In reply to: PG Bug reporting form (#1)
Re: BUG #19097: System catalog modifications are allowed by alter

On Wed, 29 Oct 2025 at 16:02, PG Bug reporting form
<noreply@postgresql.org> wrote:

The following bug has been logged on the website:

Bug reference: 19097
Logged by: RekGRpth
Email address: rekgrpth@gmail.com
PostgreSQL version: 18.0
Operating system: docker alpine
Description:

```sql
create table pg_catalog.t (i int);
ERROR: permission denied to create "pg_catalog.t"
DETAIL: System catalog modifications are currently disallowed.

create table t (i int);
CREATE TABLE

alter table t set schema pg_catalog;
ALTER TABLE

\dS+ t
Table "pg_catalog.t"
Column | Type | Collation | Nullable | Default | Storage | Compression |
Stats target | Description
--------+---------+-----------+----------+---------+---------+-------------+--------------+-------------
i | integer | | | | plain | |
|
Replica Identity: NOTHING
Access method: heap

drop table pg_catalog.t;
DROP TABLE
```

reproduced here on v13, v16, v18 and HEAD. Looks like we need to teach
ExecAlterObjectSchemaStmt to respect allow_system_table_mods GUC.
PFA doing this by adding checks to CheckSetNamespace

--
Best regards,
Kirill Reshke

Attachments:

v1-0001-Disallow-alter-schema-to-catalog-schema-without-p.patchapplication/octet-stream; name=v1-0001-Disallow-alter-schema-to-catalog-schema-without-p.patchDownload+11-1
#3Dilip Kumar
dilipbalaut@gmail.com
In reply to: PG Bug reporting form (#1)
Re: BUG #19097: System catalog modifications are allowed by alter

On Wed, Oct 29, 2025 at 4:32 PM PG Bug reporting form
<noreply@postgresql.org> wrote:

The following bug has been logged on the website:

Bug reference: 19097
Logged by: RekGRpth
Email address: rekgrpth@gmail.com
PostgreSQL version: 18.0
Operating system: docker alpine
Description:

```sql
create table pg_catalog.t (i int);
ERROR: permission denied to create "pg_catalog.t"
DETAIL: System catalog modifications are currently disallowed.

create table t (i int);
CREATE TABLE

alter table t set schema pg_catalog;
ALTER TABLE

\dS+ t
Table "pg_catalog.t"
Column | Type | Collation | Nullable | Default | Storage | Compression |
Stats target | Description
--------+---------+-----------+----------+---------+---------+-------------+--------------+-------------
i | integer | | | | plain | |
|
Replica Identity: NOTHING
Access method: heap

drop table pg_catalog.t;
DROP TABLE

Seems like this is intentionally kept like this, here is what comments
in heap_create says. Not sure what's the exact reason for not
allowing it to be created directly and it allowed to move it to
pg_catalog.

/*
* Don't allow creating relations in pg_catalog directly, even though it
* is allowed to move user defined relations there. Semantics with search
* paths including pg_catalog are too confusing for now.
*
* But allow creating indexes on relations in pg_catalog even if
* allow_system_table_mods = off, upper layers already guarantee it's on a
* user defined relation, not a system one.
*/
if (!allow_system_table_mods &&
((IsCatalogNamespace(relnamespace) && relkind != RELKIND_INDEX) ||
IsToastNamespace(relnamespace)) &&
IsNormalProcessingMode())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied to create \"%s.%s\"",
get_namespace_name(relnamespace), relname),
errdetail("System catalog modifications are currently disallowed.")));

--
Regards,
Dilip Kumar
Google

#4Laurenz Albe
laurenz.albe@cybertec.at
In reply to: PG Bug reporting form (#1)
Re: BUG #19097: System catalog modifications are allowed by alter

On Wed, 2025-10-29 at 04:41 +0000, PG Bug reporting form wrote:

PostgreSQL version: 18.0

```sql
create table pg_catalog.t (i int);
ERROR: permission denied to create "pg_catalog.t"
DETAIL: System catalog modifications are currently disallowed.

create table t (i int);
CREATE TABLE

alter table t set schema pg_catalog;
ALTER TABLE

\dS+ t
Table "pg_catalog.t"
Column | Type | Collation | Nullable | Default | Storage | Compression |
Stats target | Description
--------+---------+-----------+----------+---------+---------+-------------+--------------+-------------
i | integer | | | | plain | |

Replica Identity: NOTHING
Access method: heap

drop table pg_catalog.t;
DROP TABLE
```

That is confusing, but it seems intentional. See the following comment in
src/backend/catalog/heap.c:

/*
* Don't allow creating relations in pg_catalog directly, even though it
* is allowed to move user defined relations there. Semantics with search
* paths including pg_catalog are too confusing for now.
*
* But allow creating indexes on relations in pg_catalog even if
* allow_system_table_mods = off, upper layers already guarantee it's on a
* user defined relation, not a system one.
*/

This was deliberately added by commit 8e18d04d4daf.
I couldn't find the pertinent discussion in the archives.

I don't think it is necessary to document that...

Yours,
Laurenz Albe

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Kirill Reshke (#2)
Re: BUG #19097: System catalog modifications are allowed by alter

Kirill Reshke <reshkekirill@gmail.com> writes:

reproduced here on v13, v16, v18 and HEAD. Looks like we need to teach
ExecAlterObjectSchemaStmt to respect allow_system_table_mods GUC.

allow_system_table_mods has never been intended to be bulletproof,
only to slow down careless superusers. I'm not especially concerned
about whether there are paths it doesn't cover.

regards, tom lane