public inbox for [email protected]
help / color / mirror / Atom feedFrom: Daniil Davydov <[email protected]>
To: Jim Jones <[email protected]>
Cc: Soumya S Murali <[email protected]>
Cc: Tom Lane <[email protected]>
Cc: Stepan Neretin <[email protected]>
Cc: PostgreSQL Hackers <[email protected]>
Subject: Re: Fix bug with accessing to temporary tables of other sessions
Date: Fri, 10 Apr 2026 22:28:01 +0700
Message-ID: <CAJDiXgiJ6=79TKnB7qfEGB4UPDZQ7poxDTuvXpZT7e6sBEbfRA@mail.gmail.com> (raw)
In-Reply-To: <[email protected]>
References: <CAJDiXghdFcZ8=nh4G69te7iRr3Q0uFyXxb3ZdG09_GTNZXwH0g@mail.gmail.com>
<CAJDiXgi7tWm_y0i7kD8fMxGe=86_W-hMxyQS+g7-7cdTzd-KRQ@mail.gmail.com>
<CAMtXxw_ta_9i=uPJMvGueOBc04crmraJXcyJhN0K=Wu9aa2rog@mail.gmail.com>
<[email protected]>
<[email protected]>
<CAJDiXgh9g4TEyF3kWCiBgHX6QbpATZtxTfrQuBCKxUO5=nZBOw@mail.gmail.com>
<[email protected]>
<CAJDiXgihovkP6DMAFyJtYF4JSAjvKmiRVbF5R5n3SA=Yag32_w@mail.gmail.com>
<CAMtXxw8pHLH9+mG3wxsF8f=Y+pHqTNP8X1UmZQPkRL9pZ5aF2w@mail.gmail.com>
<[email protected]>
<[email protected]>
<CAJDiXgiAObr4c+PTWSS19vcohrFSDLK3MC5FK3TekMB3U3DjfQ@mail.gmail.com>
<[email protected]>
<CAJDiXghBO_TqvHOSui8MOxiFmwLT20+SAnH5nW1rpWHk7Jwffg@mail.gmail.com>
<[email protected]>
<CAJDiXgi0JFk0f2KWWQkzLBC5P7erX9WP18qqnbi-rjZ-K-P=3w@mail.gmail.com>
<[email protected]>
Hi,
On Fri, Apr 10, 2026 at 5:29 PM Jim Jones <[email protected]> wrote:
>
> > BTW, what do you think about making this comment less "concrete"? :
> > # SELECT via index scan from other session.
> > # Sequential scans are blocked at read_stream_begin_relation(); index scans
> > # bypass that path entirely and reach ReadBufferExtended() in bufmgr.c
> > # (nbtree's _bt_getbuf calls ReadBuffer directly for individual page fetches).
> > # enable_seqscan=off forces the planner to use the index.
> >
> > I mean that if the described logic changes, this comment will become confusing.
> > We can describe the test in general words. For example :
> > # Index scans can use a different code path from the one sequential scans are
> > # following. Make sure that we cannot access other sessions' temp tables during
> > # index scan either.
>
> +1
>
> Yeah, it's indeed too verbose. I guess these comments were originally
> just for me so I wouldn't get too confused along the way :)
OK :)
>
> I don't have anything else to add at this point. Unless there are any
> objections, I'll mark the CF entry as 'Ready for Committer.'
>
Great, thank you!
Please, see an updated set of patches (only perl test has been changed) :
1) Rephrase the discussed comment.
2) Use safe_psql whenever possible.
3) Run pgperltidy.
--
Best regards,
Daniil Davydov
Attachments:
[text/x-patch] v17-0001-Prevent-access-to-other-sessions-temp-tables.patch (3.3K, 2-v17-0001-Prevent-access-to-other-sessions-temp-tables.patch)
download | inline diff:
From 9045b387f7722193d4239dc2dbb73793f3978866 Mon Sep 17 00:00:00 2001
From: Daniil Davidov <[email protected]>
Date: Fri, 10 Apr 2026 13:51:14 +0700
Subject: [PATCH v17 1/2] Prevent access to other sessions' temp tables
---
src/backend/storage/aio/read_stream.c | 10 ++++++++++
src/backend/storage/buffer/bufmgr.c | 16 ++++++++++++++--
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/src/backend/storage/aio/read_stream.c b/src/backend/storage/aio/read_stream.c
index b6fce4e7cc6..213f6206ba2 100644
--- a/src/backend/storage/aio/read_stream.c
+++ b/src/backend/storage/aio/read_stream.c
@@ -776,6 +776,16 @@ read_stream_begin_impl(int flags,
uint32 max_possible_buffer_limit;
Oid tablespace_id;
+ /*
+ * Reject attempts to read non-local temporary relations; we would be
+ * likely to get wrong data since we have no visibility into the owning
+ * session's local buffers.
+ */
+ if (rel && RELATION_IS_OTHER_TEMP(rel))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot access temporary relations of other sessions")));
+
/*
* Decide how many I/Os we will allow to run at the same time. That
* currently means advice to the kernel to tell it that we will soon read.
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 3cc0b0bdd92..70353f1f8e3 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -795,7 +795,7 @@ PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum)
if (RELATION_IS_OTHER_TEMP(reln))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot access temporary tables of other sessions")));
+ errmsg("cannot access temporary relations of other sessions")));
/* pass it off to localbuf.c */
return PrefetchLocalBuffer(RelationGetSmgr(reln), forkNum, blockNum);
@@ -936,7 +936,7 @@ ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum,
if (RELATION_IS_OTHER_TEMP(reln))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot access temporary tables of other sessions")));
+ errmsg("cannot access temporary relations of other sessions")));
/*
* Read the buffer, and update pgstat counters to reflect a cache hit or
@@ -1292,6 +1292,12 @@ ReadBuffer_common(Relation rel, SMgrRelation smgr, char smgr_persistence,
int flags;
char persistence;
+ /* see comments in ReadBufferExtended */
+ if (rel && RELATION_IS_OTHER_TEMP(rel))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot access temporary relations of other sessions")));
+
/*
* Backward compatibility path, most code should use ExtendBufferedRel()
* instead, as acquiring the extension lock inside ExtendBufferedRel()
@@ -1382,6 +1388,12 @@ StartReadBuffersImpl(ReadBuffersOperation *operation,
Assert(*nblocks > 0);
Assert(*nblocks <= MAX_IO_COMBINE_LIMIT);
+ /* see comments in ReadBufferExtended */
+ if (operation->rel && RELATION_IS_OTHER_TEMP(operation->rel))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot access temporary relations of other sessions")));
+
if (operation->persistence == RELPERSISTENCE_TEMP)
{
io_context = IOCONTEXT_NORMAL;
--
2.43.0
[text/x-patch] v17-0002-Test-cross-session-access-on-temporary-tables.patch (4.3K, 3-v17-0002-Test-cross-session-access-on-temporary-tables.patch)
download | inline diff:
From 91a6caa33c68afd73e0418972d5a582fe6fd7bdf Mon Sep 17 00:00:00 2001
From: Daniil Davidov <[email protected]>
Date: Fri, 10 Apr 2026 22:21:23 +0700
Subject: [PATCH v17 2/2] Test cross session access on temporary tables
---
src/test/modules/test_misc/meson.build | 1 +
.../test_misc/t/012_temp_obj_multisession.pl | 109 ++++++++++++++++++
2 files changed, 110 insertions(+)
create mode 100644 src/test/modules/test_misc/t/012_temp_obj_multisession.pl
diff --git a/src/test/modules/test_misc/meson.build b/src/test/modules/test_misc/meson.build
index 1b25d98f7f3..a54599cc301 100644
--- a/src/test/modules/test_misc/meson.build
+++ b/src/test/modules/test_misc/meson.build
@@ -20,6 +20,7 @@ tests += {
't/009_log_temp_files.pl',
't/010_index_concurrently_upsert.pl',
't/011_lock_stats.pl',
+ 't/012_temp_obj_multisession.pl',
],
# The injection points are cluster-wide, so disable installcheck
'runningcheck': false,
diff --git a/src/test/modules/test_misc/t/012_temp_obj_multisession.pl b/src/test/modules/test_misc/t/012_temp_obj_multisession.pl
new file mode 100644
index 00000000000..fa8037e4d1e
--- /dev/null
+++ b/src/test/modules/test_misc/t/012_temp_obj_multisession.pl
@@ -0,0 +1,109 @@
+# Copyright (c) 2026, PostgreSQL Global Development Group
+
+use strict;
+use warnings;
+use PostgreSQL::Test::Cluster;
+use PostgreSQL::Test::Utils;
+use PostgreSQL::Test::BackgroundPsql;
+use Test::More;
+
+# Set up a fresh node
+my $node = PostgreSQL::Test::Cluster->new('temp_lock');
+$node->init;
+$node->start;
+
+# Create a long-lived session
+my $psql1 = $node->background_psql('postgres');
+
+$psql1->query_safe(q(CREATE TEMP TABLE foo AS SELECT 42 AS val;));
+
+$psql1->query_safe(q(CREATE INDEX ON foo(val);));
+
+my $tempschema = $node->safe_psql(
+ 'postgres',
+ q{
+ SELECT n.nspname
+ FROM pg_class c
+ JOIN pg_namespace n ON n.oid = c.relnamespace
+ WHERE relname = 'foo' AND relpersistence = 't';
+ }
+);
+chomp $tempschema;
+ok($tempschema =~ /^pg_temp_\d+$/, "got temp schema: $tempschema");
+
+
+# SELECT TEMPORARY TABLE from other session
+my ($stdout, $stderr);
+$node->psql(
+ 'postgres',
+ "SELECT val FROM $tempschema.foo;",
+ stdout => \$stdout,
+ stderr => \$stderr);
+like(
+ $stderr,
+ qr/cannot access temporary relations of other sessions/,
+ 'SELECT on other session temp table is not allowed');
+
+# UPDATE TEMPORARY TABLE from other session
+$node->psql(
+ 'postgres',
+ "UPDATE $tempschema.foo SET val = NULL;",
+ stderr => \$stderr);
+like(
+ $stderr,
+ qr/cannot access temporary relations of other sessions/,
+ 'UPDATE on other session temp table is not allowed');
+
+# DELETE records from TEMPORARY TABLE from other session
+$node->psql('postgres', "DELETE FROM $tempschema.foo;", stderr => \$stderr);
+like(
+ $stderr,
+ qr/cannot access temporary relations of other sessions/,
+ 'DELETE on other session temp table is not allowed');
+
+# TRUNCATE TEMPORARY TABLE from other session
+$node->psql('postgres', "TRUNCATE TABLE $tempschema.foo;",
+ stderr => \$stderr);
+like(
+ $stderr,
+ qr/cannot truncate temporary tables of other sessions/,
+ 'TRUNCATE on other session temp table is not allowed');
+
+# INSERT INTO TEMPORARY TABLE from other session
+$node->psql(
+ 'postgres',
+ "INSERT INTO $tempschema.foo VALUES (73);",
+ stderr => \$stderr);
+like(
+ $stderr,
+ qr/cannot access temporary relations of other sessions/,
+ 'INSERT INTO on other session temp table is not allowed');
+
+# COPY TEMPORARY TABLE from other session
+$node->psql('postgres', "COPY $tempschema.foo TO STDOUT;",
+ stderr => \$stderr);
+like(
+ $stderr,
+ qr/cannot access temporary relations of other sessions/,
+ 'COPY on other session temp table is blocked');
+
+# Index scans can use a different code path from the one sequential scans are
+# following. Make sure that we cannot access other sessions' temp tables during
+# index scan either.
+$node->psql(
+ 'postgres',
+ "SET enable_seqscan = off; SELECT val FROM $tempschema.foo WHERE val = 42;",
+ stderr => \$stderr);
+like(
+ $stderr,
+ qr/cannot access temporary relations of other sessions/,
+ 'index scan on other session temp table is not allowed (exercises ReadBufferExtended path)'
+);
+
+# DROP TEMPORARY TABLE from other session
+$node->safe_psql('postgres', "DROP TABLE $tempschema.foo;");
+
+# Clean up
+$psql1->quit;
+
+done_testing();
--
2.43.0
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected], [email protected], [email protected]
Subject: Re: Fix bug with accessing to temporary tables of other sessions
In-Reply-To: <CAJDiXgiJ6=79TKnB7qfEGB4UPDZQ7poxDTuvXpZT7e6sBEbfRA@mail.gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox