agora inbox for pgsql-committers@postgresql.org  
help / color / mirror / Atom feed
pgsql: Prevent access to other sessions' temp tables
3+ messages / 1 participants
[nested] [flat]

* pgsql: Prevent access to other sessions' temp tables
@ 2026-05-14 12:05  Alexander Korotkov <akorotkov@postgresql.org>
  0 siblings, 0 replies; 3+ messages in thread

From: Alexander Korotkov @ 2026-05-14 12:05 UTC (permalink / raw)
  To: pgsql-committers@lists.postgresql.org

Prevent access to other sessions' temp tables

Commit b7b0f3f2724 ("Use streaming I/O in sequential scans") routed
sequential scans through read_stream_next_buffer(), bypassing the
RELATION_IS_OTHER_TEMP() check in ReadBufferExtended().  As a result,
a superuser can attempt to read or modify temp tables of other
sessions through the read-stream path.  When the query plan uses no index,
SELECT/UPDATE/DELETE/MERGE silently see no rows / report zero affected rows,
and COPY produces an empty output -- because the buffer manager has no
visibility into the owning session's local buffers and silently returns
nothing.  Any query plan that uses, for instance, a btree index
still errors out via the existing check in ReadBufferExtended(), which
is reached from hio.c and nbtree respectively, but this is incidental.

Fix by enforcing RELATION_IS_OTHER_TEMP() at the three additional
buffer-manager entry points:

- read_stream_begin_impl() rejects the read at stream setup time,
  covering sequential and bitmap scans that go through the
  read-stream path.
- ReadBuffer_common() becomes the canonical place for the check,
  consolidating the existing one previously kept in
  ReadBufferExtended().  All ReadBufferExtended() callers go through
  ReadBuffer_common(), so the consolidation is behavior-preserving.
- StartReadBuffersImpl() catches direct callers of StartReadBuffers()
  that bypass both of the above.  This is currently defense-in-depth,
  but documents the contract for future code.

The companion test in src/test/modules/test_misc was added in the
preceding commit; this commit updates the assertions for SELECT,
UPDATE, DELETE, MERGE, and COPY (which previously documented the
bug as silent success) to expect the new error.

Author: Jim Jones <jim.jones@uni-muenster.de>
Author: Daniil Davydov <3danissimo@gmail.com>
Co-authored-by: Alexander Korotkov <aekorotkov@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Soumya S Murali <soumyamurali.work@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAJDiXghdFcZ8%3Dnh4G69te7iRr3Q0uFyXxb3ZdG09_GTNZXwH0g%40mail.gmail.com
Backpatch-through: 17

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/ce146621f7860d2e19c509f1466feca3bf777678

Modified Files
--------------
src/backend/storage/aio/read_stream.c              | 10 +++++++
src/backend/storage/buffer/bufmgr.c                | 33 ++++++++++++++--------
src/include/utils/rel.h                            | 17 ++++-------
.../test_misc/t/013_temp_obj_multisession.pl       | 27 ++++++++----------
4 files changed, 48 insertions(+), 39 deletions(-)



^ permalink  raw  reply  [nested|flat] 3+ messages in thread

* pgsql: Prevent access to other sessions' temp tables
@ 2026-05-14 12:06  Alexander Korotkov <akorotkov@postgresql.org>
  0 siblings, 0 replies; 3+ messages in thread

From: Alexander Korotkov @ 2026-05-14 12:06 UTC (permalink / raw)
  To: pgsql-committers@lists.postgresql.org

Prevent access to other sessions' temp tables

Commit b7b0f3f2724 ("Use streaming I/O in sequential scans") routed
sequential scans through read_stream_next_buffer(), bypassing the
RELATION_IS_OTHER_TEMP() check in ReadBufferExtended().  As a result,
a superuser can attempt to read or modify temp tables of other
sessions through the read-stream path.  When the query plan uses no index,
SELECT/UPDATE/DELETE/MERGE silently see no rows / report zero affected rows,
and COPY produces an empty output -- because the buffer manager has no
visibility into the owning session's local buffers and silently returns
nothing.  Any query plan that uses, for instance, a btree index
still errors out via the existing check in ReadBufferExtended(), which
is reached from hio.c and nbtree respectively, but this is incidental.

Fix by enforcing RELATION_IS_OTHER_TEMP() at the three additional
buffer-manager entry points:

- read_stream_begin_impl() rejects the read at stream setup time,
  covering sequential and bitmap scans that go through the
  read-stream path.
- ReadBuffer_common() becomes the canonical place for the check,
  consolidating the existing one previously kept in
  ReadBufferExtended().  All ReadBufferExtended() callers go through
  ReadBuffer_common(), so the consolidation is behavior-preserving.
- StartReadBuffersImpl() catches direct callers of StartReadBuffers()
  that bypass both of the above.  This is currently defense-in-depth,
  but documents the contract for future code.

The companion test in src/test/modules/test_misc was added in the
preceding commit; this commit updates the assertions for SELECT,
UPDATE, DELETE, MERGE, and COPY (which previously documented the
bug as silent success) to expect the new error.

Author: Jim Jones <jim.jones@uni-muenster.de>
Author: Daniil Davydov <3danissimo@gmail.com>
Co-authored-by: Alexander Korotkov <aekorotkov@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Soumya S Murali <soumyamurali.work@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAJDiXghdFcZ8%3Dnh4G69te7iRr3Q0uFyXxb3ZdG09_GTNZXwH0g%40mail.gmail.com
Backpatch-through: 17

Branch
------
REL_18_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/1b0dd08157bf945909849c5e73d9e3f5b057c63b

Modified Files
--------------
src/backend/storage/aio/read_stream.c              | 10 +++++++
src/backend/storage/buffer/bufmgr.c                | 33 ++++++++++++++--------
src/include/utils/rel.h                            | 17 ++++-------
.../test_misc/t/013_temp_obj_multisession.pl       | 27 ++++++++----------
4 files changed, 48 insertions(+), 39 deletions(-)



^ permalink  raw  reply  [nested|flat] 3+ messages in thread

* pgsql: Prevent access to other sessions' temp tables
@ 2026-05-14 12:08  Alexander Korotkov <akorotkov@postgresql.org>
  0 siblings, 0 replies; 3+ messages in thread

From: Alexander Korotkov @ 2026-05-14 12:08 UTC (permalink / raw)
  To: pgsql-committers@lists.postgresql.org

Prevent access to other sessions' temp tables

Commit b7b0f3f2724 ("Use streaming I/O in sequential scans") routed
sequential scans through read_stream_next_buffer(), bypassing the
RELATION_IS_OTHER_TEMP() check in ReadBufferExtended().  As a result,
a superuser can attempt to read or modify temp tables of other
sessions through the read-stream path.  When the query plan uses no index,
SELECT/UPDATE/DELETE/MERGE silently see no rows / report zero affected rows,
and COPY produces an empty output -- because the buffer manager has no
visibility into the owning session's local buffers and silently returns
nothing.  Any query plan that uses, for instance, a btree index
still errors out via the existing check in ReadBufferExtended(), which
is reached from hio.c and nbtree respectively, but this is incidental.

Fix by enforcing RELATION_IS_OTHER_TEMP() at the three additional
buffer-manager entry points:

- read_stream_begin_impl() rejects the read at stream setup time,
  covering sequential and bitmap scans that go through the
  read-stream path.
- ReadBuffer_common() becomes the canonical place for the check,
  consolidating the existing one previously kept in
  ReadBufferExtended().  All ReadBufferExtended() callers go through
  ReadBuffer_common(), so the consolidation is behavior-preserving.
- StartReadBuffersImpl() catches direct callers of StartReadBuffers()
  that bypass both of the above.  This is currently defense-in-depth,
  but documents the contract for future code.

The companion test in src/test/modules/test_misc was added in the
preceding commit; this commit updates the assertions for SELECT,
UPDATE, DELETE, MERGE, and COPY (which previously documented the
bug as silent success) to expect the new error.

Author: Jim Jones <jim.jones@uni-muenster.de>
Author: Daniil Davydov <3danissimo@gmail.com>
Co-authored-by: Alexander Korotkov <aekorotkov@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Soumya S Murali <soumyamurali.work@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAJDiXghdFcZ8%3Dnh4G69te7iRr3Q0uFyXxb3ZdG09_GTNZXwH0g%40mail.gmail.com
Backpatch-through: 17

Branch
------
REL_17_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/4dfae59a1d31651adec524cbeb386c6c3e5f8cba

Modified Files
--------------
src/backend/storage/aio/read_stream.c              | 10 +++++++
src/backend/storage/buffer/bufmgr.c                | 33 ++++++++++++++--------
src/include/utils/rel.h                            | 17 ++++-------
.../test_misc/t/013_temp_obj_multisession.pl       | 27 ++++++++----------
4 files changed, 48 insertions(+), 39 deletions(-)



^ permalink  raw  reply  [nested|flat] 3+ messages in thread


end of thread, other threads:[~2026-05-14 12:08 UTC | newest]

Thread overview: 3+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2026-05-14 12:05 pgsql: Prevent access to other sessions' temp tables Alexander Korotkov <akorotkov@postgresql.org>
2026-05-14 12:06 pgsql: Prevent access to other sessions' temp tables Alexander Korotkov <akorotkov@postgresql.org>
2026-05-14 12:08 pgsql: Prevent access to other sessions' temp tables Alexander Korotkov <akorotkov@postgresql.org>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox