Temp schema drop leaves an inconsistent state behind - Mailing list pgsql-hackers

From Marko Grujic
Subject Temp schema drop leaves an inconsistent state behind
Date
Msg-id CAOvwyF2r=uNK+pPRuA2EqJeLZNMS-QtrTFVk2N6dse4EothP1w@mail.gmail.com
Whole thread
Responses Re: Temp schema drop leaves an inconsistent state behind
List pgsql-hackers
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
Attachment

pgsql-hackers by date:

Previous
From: Alexandre Felipe
Date:
Subject: [patch] Cache invalidation for I/O Workers
Next
From: Yugo Nagata
Date:
Subject: Re: JIT works only partially with meson build?