Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb5c5743

Browse files
committed
Avoid repeated name lookups during table and index DDL.
If the name lookups come to different conclusions due to concurrentactivity, we might perform some parts of the DDL on a different tablethan other parts. At least in the case of CREATE INDEX, this can beused to cause the permissions checks to be performed against adifferent table than the index creation, allowing for a privilegeescalation attack.This changes the calling convention for DefineIndex, CreateTrigger,transformIndexStmt, transformAlterTableStmt, CheckIndexCompatible(in 9.2 and newer), and AlterTable (in 9.1 and older). In addition,CheckRelationOwnership is removed in 9.2 and newer and the callingconvention is changed in older branches. A field has also been addedto the Constraint node (FkConstraint in 8.4). Third-party code callingthese functions or using the Constraint node will require updating.Report by Andres Freund. Patch by Robert Haas and Andres Freund,reviewed by Tom Lane.Security:CVE-2014-0062
1 parent338daaf commitb5c5743

File tree

20 files changed

+233
-130
lines changed

20 files changed

+233
-130
lines changed

‎src/backend/bootstrap/bootparse.y

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include"bootstrap/bootstrap.h"
2828
#include"catalog/catalog.h"
2929
#include"catalog/heap.h"
30+
#include"catalog/namespace.h"
3031
#include"catalog/pg_am.h"
3132
#include"catalog/pg_attribute.h"
3233
#include"catalog/pg_authid.h"
@@ -279,9 +280,14 @@ Boot_InsertStmt:
279280
Boot_DeclareIndexStmt:
280281
XDECLAREINDEXboot_identoidspecONboot_identUSINGboot_identLPARENboot_index_paramsRPAREN
281282
{
283+
OidrelationId;
284+
282285
do_start();
283286

284-
DefineIndex(makeRangeVar(NULL, $6, -1),
287+
relationId = RangeVarGetRelid(makeRangeVar(NULL,$6, -1),
288+
false);
289+
290+
DefineIndex(relationId,
285291
$3,
286292
$4,
287293
$8,
@@ -297,9 +303,14 @@ Boot_DeclareIndexStmt:
297303
Boot_DeclareUniqueIndexStmt:
298304
XDECLAREUNIQUEINDEXboot_identoidspecONboot_identUSINGboot_identLPARENboot_index_paramsRPAREN
299305
{
306+
OidrelationId;
307+
300308
do_start();
301309

302-
DefineIndex(makeRangeVar(NULL, $7, -1),
310+
relationId = RangeVarGetRelid(makeRangeVar(NULL,$7, -1),
311+
false);
312+
313+
DefineIndex(relationId,
303314
$4,
304315
$5,
305316
$9,

‎src/backend/catalog/index.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ static void validate_index_heapscan(Relation heapRelation,
115115
IndexInfo*indexInfo,
116116
Snapshotsnapshot,
117117
v_i_state*state);
118-
staticOidIndexGetRelation(OidindexId);
119118
staticboolReindexIsCurrentlyProcessingIndex(OidindexOid);
120119
staticvoidSetReindexProcessing(OidheapOid,OidindexOid);
121120
staticvoidResetReindexProcessing(void);
@@ -1202,18 +1201,13 @@ index_constraint_create(Relation heapRelation,
12021201
*/
12031202
if (deferrable)
12041203
{
1205-
RangeVar*heapRel;
12061204
CreateTrigStmt*trigger;
12071205

1208-
heapRel=makeRangeVar(get_namespace_name(namespaceId),
1209-
pstrdup(RelationGetRelationName(heapRelation)),
1210-
-1);
1211-
12121206
trigger=makeNode(CreateTrigStmt);
12131207
trigger->trigname= (constraintType==CONSTRAINT_PRIMARY) ?
12141208
"PK_ConstraintTrigger" :
12151209
"Unique_ConstraintTrigger";
1216-
trigger->relation=heapRel;
1210+
trigger->relation=NULL;
12171211
trigger->funcname=SystemFuncName("unique_key_recheck");
12181212
trigger->args=NIL;
12191213
trigger->row= true;
@@ -1226,7 +1220,8 @@ index_constraint_create(Relation heapRelation,
12261220
trigger->initdeferred=initdeferred;
12271221
trigger->constrrel=NULL;
12281222

1229-
(void)CreateTrigger(trigger,NULL,conOid,indexRelationId, true);
1223+
(void)CreateTrigger(trigger,NULL,RelationGetRelid(heapRelation),
1224+
InvalidOid,conOid,indexRelationId, true);
12301225
}
12311226

12321227
/*
@@ -2833,7 +2828,7 @@ index_set_state_flags(Oid indexId, IndexStateFlagsAction action)
28332828
* IndexGetRelation: given an index's relation OID, get the OID of the
28342829
* relation it is an index on.Uses the system cache.
28352830
*/
2836-
staticOid
2831+
Oid
28372832
IndexGetRelation(OidindexId)
28382833
{
28392834
HeapTupletuple;

‎src/backend/catalog/pg_constraint.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,25 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
742742
heap_close(conRel,RowExclusiveLock);
743743
}
744744

745+
/*
746+
* get_constraint_relation_oids
747+
*Find the IDs of the relations to which a constraint refers.
748+
*/
749+
void
750+
get_constraint_relation_oids(Oidconstraint_oid,Oid*conrelid,Oid*confrelid)
751+
{
752+
HeapTupletup;
753+
Form_pg_constraintcon;
754+
755+
tup=SearchSysCache1(CONSTROID,ObjectIdGetDatum(constraint_oid));
756+
if (!HeapTupleIsValid(tup))/* should not happen */
757+
elog(ERROR,"cache lookup failed for constraint %u",constraint_oid);
758+
con= (Form_pg_constraint)GETSTRUCT(tup);
759+
*conrelid=con->conrelid;
760+
*confrelid=con->confrelid;
761+
ReleaseSysCache(tup);
762+
}
763+
745764
/*
746765
* get_constraint_oid
747766
*Find a constraint on the specified relation with the specified name.

‎src/backend/commands/alter.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,8 @@ ExecRenameStmt(RenameStmt *stmt)
105105
{
106106
Oidrelid;
107107

108-
CheckRelationOwnership(stmt->relation, true);
109-
110108
relid=RangeVarGetRelid(stmt->relation, false);
109+
CheckRelationOwnership(relid, true);
111110

112111
switch (stmt->renameType)
113112
{
@@ -223,7 +222,6 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
223222
caseOBJECT_TABLE:
224223
caseOBJECT_VIEW:
225224
caseOBJECT_FOREIGN_TABLE:
226-
CheckRelationOwnership(stmt->relation, true);
227225
AlterTableNamespace(stmt->relation,stmt->newschema,
228226
stmt->objectType,AccessExclusiveLock);
229227
break;

‎src/backend/commands/indexcmds.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ static char *ChooseIndexNameAddition(List *colnames);
7676
* DefineIndex
7777
*Creates a new index.
7878
*
79-
* 'heapRelation': the relation the index will apply to.
79+
* 'relationId': the OID of the heap relation on which the index is to be
80+
*created
8081
* 'indexRelationName': the name for the new index, or NULL to indicate
8182
*that a nonconflicting default name should be picked.
8283
* 'indexRelationId': normally InvalidOid, but during bootstrap can be
@@ -105,7 +106,7 @@ static char *ChooseIndexNameAddition(List *colnames);
105106
* 'concurrent': avoid blocking writers to the table while building.
106107
*/
107108
void
108-
DefineIndex(RangeVar*heapRelation,
109+
DefineIndex(OidrelationId,
109110
char*indexRelationName,
110111
OidindexRelationId,
111112
char*accessMethodName,
@@ -128,7 +129,6 @@ DefineIndex(RangeVar *heapRelation,
128129
Oid*collationObjectId;
129130
Oid*classObjectId;
130131
OidaccessMethodId;
131-
OidrelationId;
132132
OidnamespaceId;
133133
OidtablespaceId;
134134
List*indexColNames;
@@ -148,6 +148,7 @@ DefineIndex(RangeVar *heapRelation,
148148
intn_old_snapshots;
149149
LockRelIdheaprelid;
150150
LOCKTAGheaplocktag;
151+
LOCKMODElockmode;
151152
Snapshotsnapshot;
152153
inti;
153154

@@ -166,14 +167,18 @@ DefineIndex(RangeVar *heapRelation,
166167
INDEX_MAX_KEYS)));
167168

168169
/*
169-
* Open heap relation, acquire a suitable lock on it, remember its OID
170-
*
171170
* Only SELECT ... FOR UPDATE/SHARE are allowed while doing a standard
172171
* index build; but for concurrent builds we allow INSERT/UPDATE/DELETE
173172
* (but not VACUUM).
173+
*
174+
* NB: Caller is responsible for making sure that relationId refers
175+
* to the relation on which the index should be built; except in bootstrap
176+
* mode, this will typically require the caller to have already locked
177+
* the relation. To avoid lock upgrade hazards, that lock should be at
178+
* least as strong as the one we take here.
174179
*/
175-
rel=heap_openrv(heapRelation,
176-
(concurrent ?ShareUpdateExclusiveLock :ShareLock));
180+
lockmode=concurrent ?ShareUpdateExclusiveLock :ShareLock;
181+
rel=heap_open(relationId,lockmode);
177182

178183
relationId=RelationGetRelid(rel);
179184
namespaceId=RelationGetNamespace(rel);
@@ -191,12 +196,12 @@ DefineIndex(RangeVar *heapRelation,
191196
ereport(ERROR,
192197
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
193198
errmsg("cannot create index on foreign table \"%s\"",
194-
heapRelation->relname)));
199+
RelationGetRelationName(rel))));
195200
else
196201
ereport(ERROR,
197202
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
198203
errmsg("\"%s\" is not a table",
199-
heapRelation->relname)));
204+
RelationGetRelationName(rel))));
200205
}
201206

202207
/*
@@ -503,7 +508,7 @@ DefineIndex(RangeVar *heapRelation,
503508
*/
504509

505510
/* Open and lock the parent heap relation */
506-
rel=heap_openrv(heapRelation,ShareUpdateExclusiveLock);
511+
rel=heap_open(relationId,ShareUpdateExclusiveLock);
507512

508513
/* And the target index relation */
509514
indexRelation=index_open(indexRelationId,RowExclusiveLock);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp