Fix contrib/pgstattuple and contrib/pageinspect to prevent attempts to read
authorTom Lane
Tue, 31 Mar 2009 22:54:31 +0000 (22:54 +0000)
committerTom Lane
Tue, 31 Mar 2009 22:54:31 +0000 (22:54 +0000)
temporary tables of other sessions; that is unsafe because of the way our
buffer management works.  Per report from Stuart Bishop.
This is redundant with the bufmgr.c checks in HEAD, but not at all redundant
in the back branches.

contrib/pageinspect/btreefuncs.c
contrib/pageinspect/rawpage.c
contrib/pgstattuple/pgstatindex.c
contrib/pgstattuple/pgstattuple.c

index ab80b545000b66de31f0206a962b28407991f731..85935b99905627a1928ae7134ce4befa9c2fe19e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/pageinspect/btreefuncs.c,v 1.8 2008/05/17 01:28:19 adunstan Exp $ 
+ * $PostgreSQL: pgsql/contrib/pageinspect/btreefuncs.c,v 1.9 2009/03/31 22:54:31 tgl Exp $ 
  *
  *
  * btreefuncs.c
@@ -190,6 +190,16 @@ bt_page_stats(PG_FUNCTION_ARGS)
        elog(ERROR, "relation \"%s\" is not a btree index",
             RelationGetRelationName(rel));
 
+   /*
+    * 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 (RELATION_IS_OTHER_TEMP(rel))
+       ereport(ERROR,
+               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                errmsg("cannot access temporary tables of other sessions")));
+
    if (blkno == 0)
        elog(ERROR, "block 0 is a meta page");
 
@@ -298,6 +308,16 @@ bt_page_items(PG_FUNCTION_ARGS)
            elog(ERROR, "relation \"%s\" is not a btree index",
                 RelationGetRelationName(rel));
 
+       /*
+        * 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 (RELATION_IS_OTHER_TEMP(rel))
+           ereport(ERROR,
+                   (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                    errmsg("cannot access temporary tables of other sessions")));
+
        if (blkno == 0)
            elog(ERROR, "block 0 is a meta page");
 
@@ -437,6 +457,16 @@ bt_metap(PG_FUNCTION_ARGS)
        elog(ERROR, "relation \"%s\" is not a btree index",
             RelationGetRelationName(rel));
 
+   /*
+    * 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 (RELATION_IS_OTHER_TEMP(rel))
+       ereport(ERROR,
+               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                errmsg("cannot access temporary tables of other sessions")));
+
    buffer = ReadBuffer(rel, 0);
    page = BufferGetPage(buffer);
    metad = BTPageGetMeta(page);
index 607f55eef0acca1bd913354dcfaff14e30915cbe..91b6a1915f0518d5d74d2fe92dff95bf681b43a6 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright (c) 2007-2009, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/contrib/pageinspect/rawpage.c,v 1.10 2009/01/01 17:23:32 momjian Exp $
+ *   $PostgreSQL: pgsql/contrib/pageinspect/rawpage.c,v 1.11 2009/03/31 22:54:31 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -74,6 +74,16 @@ get_raw_page(PG_FUNCTION_ARGS)
                 errmsg("cannot get raw page from composite type \"%s\"",
                        RelationGetRelationName(rel))));
 
+   /*
+    * 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 (RELATION_IS_OTHER_TEMP(rel))
+       ereport(ERROR,
+               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                errmsg("cannot access temporary tables of other sessions")));
+
    if (blkno >= RelationGetNumberOfBlocks(rel))
        elog(ERROR, "block number %u is out of range for relation \"%s\"",
             blkno, RelationGetRelationName(rel));
index dfb162d5e45de730d2aa84891d6c7abf34445cb3..b00ae5b766bc1d925b13fcfd977081f6f9206ebb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/pgstattuple/pgstatindex.c,v 1.11 2008/05/17 01:28:22 adunstan Exp $ 
+ * $PostgreSQL: pgsql/contrib/pgstattuple/pgstatindex.c,v 1.12 2009/03/31 22:54:31 tgl Exp $ 
  *
  *
  * pgstatindex
@@ -107,6 +107,16 @@ pgstatindex(PG_FUNCTION_ARGS)
        elog(ERROR, "relation \"%s\" is not a btree index",
             RelationGetRelationName(rel));
 
+   /*
+    * 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 (RELATION_IS_OTHER_TEMP(rel))
+       ereport(ERROR,
+               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                errmsg("cannot access temporary tables of other sessions")));
+
    /*
     * Read metapage
     */
@@ -262,6 +272,8 @@ pg_relpages(PG_FUNCTION_ARGS)
    relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
    rel = relation_openrv(relrv, AccessShareLock);
 
+   /* note: this will work OK on non-local temp tables */
+
    relpages = RelationGetNumberOfBlocks(rel);
 
    relation_close(rel, AccessShareLock);
index f4c046ca8c5c370fb6fc3c07ef8c510fb838d3f9..c2c5d11e5a65b068b641fb70bbfe170a43294046 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/pgstattuple/pgstattuple.c,v 1.36 2008/06/19 00:46:03 alvherre Exp $
+ * $PostgreSQL: pgsql/contrib/pgstattuple/pgstattuple.c,v 1.37 2009/03/31 22:54:31 tgl Exp $
  *
  * Copyright (c) 2001,2002 Tatsuo Ishii
  *
@@ -199,6 +199,16 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
 {
    const char *err;
 
+   /*
+    * 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 (RELATION_IS_OTHER_TEMP(rel))
+       ereport(ERROR,
+               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                errmsg("cannot access temporary tables of other sessions")));
+
    switch (rel->rd_rel->relkind)
    {
        case RELKIND_RELATION: