Temp schema drop leaves an inconsistent state behind

Started by Marko Grujic2 days ago1 messageshackers
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.

appliessuccessCI 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:t253844
psql -h localhost -U postgres

Built from patchset v1 (message #1), September 20, 2026 at 04:15 PM.

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 t253844_1 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 t253844_1 && git checkout t253844_1

Patchset v1 (message #1) is on t253844_1

Jump to latest
#1Marko Grujic
marko.grujic@enterprisedb.com

Hi, reporting two bugs I ran into, one breaking pg_dump and the other
leading to a segfault.

The setup (and the first bug) involves temp schema being dropped

postgres=# select version();
version
------------------------------------------------------------------------
PostgreSQL 20devel on aarch64-darwin, compiled by clang-16.0.0, 64-bit
(1 row)

postgres=# create temp table t1(a int);
CREATE TABLE
postgres=# \d t1;
Table "pg_temp_0.t1"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
a | integer | | |

postgres=# drop schema pg_temp_0 cascade;
NOTICE: drop cascades to table t1
DROP SCHEMA
postgres=# create temp table t2(a int);
CREATE TABLE
postgres=# \d t2;
Table ".t2"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
a | integer | | |
postgres=# select pg_my_temp_schema();
pg_my_temp_schema
-------------------
16409
(1 row)

Looke innocent enough, only a cosmetic issue where the temp schema isn't
shown in table display. The table itself seems to work just fine afterwards
(writes and reads)

postgres=# insert into t2 values (1), (2), (3);
INSERT 0 3
postgres=# select * from t2;
a
---
1
2
3
(3 rows)

However, trying to pg_dump that DB leads to an error

$ pg_dump -h 127.0.0.1 -p 7999 -d postgres
pg_dump: error: schema with OID 16409 does not exist

The namespace catalog entry is now gone because of the drop

postgres=# select 1 from pg_namespace where oid = 16409;
?column?
----------
(0 rows)

The reason it wasn't re-created is because the internal static variable
(myTempNamespace) is left holding the 16409 value internally.

The second bug, while independent of the first one in general, leans on the
same setup, and exposes an existing vulnerability in the pg_identify_object
function

postgres=# select oid from pg_class where relname = 't2' and relnamespace =
16409;
oid
-------
16414
(1 row)

postgres=# select pg_identify_object('pg_class'::regclass, 16414, 0);
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.

The backend logs:
LOG: client backend (PID 8145) was terminated by signal 11: Segmentation
fault: 11
DETAIL: Failed process was running: select
pg_identify_object('pg_class'::regclass, 16414, 0);

The problem is that the function doesn't giuard against get_namespace_name
returning NULL,
which quote_identifier then tries to dereference.

Attached are two patches that fix both (in reverse order, patch 1 for the
second bug, and patch 2 for the first one)

Thanks,
Marko

Attachments:

t253844_1
0001-Fix-crash-in-pg_identify_object-when-an-object-s-sch.patchapplication/octet-stream; name=0001-Fix-crash-in-pg_identify_object-when-an-object-s-sch.patchDownload+12-7
0002-Reset-myTempNamespace-when-the-temp-schema-has-been-.patchapplication/octet-stream; name=0002-Reset-myTempNamespace-when-the-temp-schema-has-been-.patchDownload+87-2