BUG #19097: System catalog modifications are allowed by alter

Started by PG Bug reporting form11 months ago5 messagesbugs
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

appliestests failedCI history

You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:

docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t73366
psql -h localhost -U postgres

Built from patchset v2 (message #2), September 20, 2026 at 02:43 AM.

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t73366_2 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t73366_2 && git checkout t73366_2

Patchset v2 (message #2) is on t73366_2

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:

t73366_2
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