Skip to content

Commit 04158e7

Browse files
committed
Avoid repeated table name lookups in createPartitionTable()
Currently, createPartitionTable() opens newly created table using its name. This approach is prone to privilege escalation attack, because we might end up opening another table than we just created. This commit address the issue above by opening newly created table by its OID. It appears to be tricky to get a relation OID out of ProcessUtility(). We have to extend TableLikeClause with new newRelationOid field, which is filled within ProcessUtility() to be further accessed by caller. Security: CVE-2014-0062 Reported-by: Noah Misch Discussion: https://postgr.es/m/20240808171351.a9.nmisch%40google.com Reviewed-by: Pavel Borisov, Dmitry Koval
1 parent 9bb842f commit 04158e7

File tree

4 files changed

+10
-1
lines changed

4 files changed

+10
-1
lines changed

src/backend/commands/tablecmds.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -20383,6 +20383,7 @@ createPartitionTable(RangeVar *newPartName, Relation modelRel,
2038320383
tlc->options = CREATE_TABLE_LIKE_ALL &
2038420384
~(CREATE_TABLE_LIKE_INDEXES | CREATE_TABLE_LIKE_IDENTITY | CREATE_TABLE_LIKE_STATISTICS);
2038520385
tlc->relationOid = InvalidOid;
20386+
tlc->newRelationOid = InvalidOid;
2038620387
createStmt->tableElts = lappend(createStmt->tableElts, tlc);
2038720388

2038820389
/* Need to make a wrapper PlannedStmt. */
@@ -20406,7 +20407,7 @@ createPartitionTable(RangeVar *newPartName, Relation modelRel,
2040620407
* Open the new partition with no lock, because we already have
2040720408
* AccessExclusiveLock placed there after creation.
2040820409
*/
20409-
newRel = table_openrv(newPartName, NoLock);
20410+
newRel = table_open(tlc->newRelationOid, NoLock);
2041020411

2041120412
/*
2041220413
* We intended to create the partition with the same persistence as the

src/backend/parser/gram.y

+1
Original file line numberDiff line numberDiff line change
@@ -4138,6 +4138,7 @@ TableLikeClause:
41384138
n->relation = $2;
41394139
n->options = $3;
41404140
n->relationOid = InvalidOid;
4141+
n->newRelationOid = InvalidOid;
41414142
$$ = (Node *) n;
41424143
}
41434144
;

src/backend/tcop/utility.c

+6
Original file line numberDiff line numberDiff line change
@@ -1225,6 +1225,12 @@ ProcessUtilitySlow(ParseState *pstate,
12251225

12261226
morestmts = expandTableLikeClause(table_rv, like);
12271227
stmts = list_concat(morestmts, stmts);
1228+
1229+
/*
1230+
* Store the OID of newly created relation to the
1231+
* TableLikeClause for the caller to use it.
1232+
*/
1233+
like->newRelationOid = address.objectId;
12281234
}
12291235
else
12301236
{

src/include/nodes/parsenodes.h

+1
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,7 @@ typedef struct TableLikeClause
754754
RangeVar *relation;
755755
bits32 options; /* OR of TableLikeOption flags */
756756
Oid relationOid; /* If table has been looked up, its OID */
757+
Oid newRelationOid; /* OID of newly created table */
757758
} TableLikeClause;
758759

759760
typedef enum TableLikeOption

0 commit comments

Comments
 (0)