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

Commit43d4e96

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 parent0551483 commit43d4e96

File tree

20 files changed

+230
-118
lines changed

20 files changed

+230
-118
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"
@@ -277,9 +278,14 @@ Boot_InsertStmt:
277278
Boot_DeclareIndexStmt:
278279
XDECLAREINDEXboot_identoidspecONboot_identUSINGboot_identLPARENboot_index_paramsRPAREN
279280
{
281+
OidrelationId;
282+
280283
do_start();
281284

282-
DefineIndex(makeRangeVar(NULL, $6, -1),
285+
relationId = RangeVarGetRelid(makeRangeVar(NULL,$6, -1),
286+
false);
287+
288+
DefineIndex(relationId,
283289
$3,
284290
$4,
285291
$8,
@@ -295,9 +301,14 @@ Boot_DeclareIndexStmt:
295301
Boot_DeclareUniqueIndexStmt:
296302
XDECLAREUNIQUEINDEXboot_identoidspecONboot_identUSINGboot_identLPARENboot_index_paramsRPAREN
297303
{
304+
OidrelationId;
305+
298306
do_start();
299307

300-
DefineIndex(makeRangeVar(NULL, $7, -1),
308+
relationId = RangeVarGetRelid(makeRangeVar(NULL,$7, -1),
309+
false);
310+
311+
DefineIndex(relationId,
301312
$4,
302313
$5,
303314
$9,

‎src/backend/catalog/index.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ static void validate_index_heapscan(Relation heapRelation,
109109
IndexInfo*indexInfo,
110110
Snapshotsnapshot,
111111
v_i_state*state);
112-
staticOidIndexGetRelation(OidindexId);
113112
staticvoidSetReindexProcessing(OidheapOid,OidindexOid);
114113
staticvoidResetReindexProcessing(void);
115114
staticvoidSetReindexPending(List*indexes);
@@ -806,17 +805,12 @@ index_create(Oid heapRelationId,
806805
*/
807806
if (deferrable)
808807
{
809-
RangeVar*heapRel;
810808
CreateTrigStmt*trigger;
811809

812-
heapRel=makeRangeVar(get_namespace_name(namespaceId),
813-
pstrdup(RelationGetRelationName(heapRelation)),
814-
-1);
815-
816810
trigger=makeNode(CreateTrigStmt);
817811
trigger->trigname= (isprimary ?"PK_ConstraintTrigger" :
818812
"Unique_ConstraintTrigger");
819-
trigger->relation=heapRel;
813+
trigger->relation=NULL;
820814
trigger->funcname=SystemFuncName("unique_key_recheck");
821815
trigger->args=NIL;
822816
trigger->before= false;
@@ -829,8 +823,8 @@ index_create(Oid heapRelationId,
829823
trigger->initdeferred=initdeferred;
830824
trigger->constrrel=NULL;
831825

832-
(void)CreateTrigger(trigger,NULL,conOid,indexRelationId,
833-
true);
826+
(void)CreateTrigger(trigger,NULL,heapRelationId,InvalidOid,
827+
conOid,indexRelationId,true);
834828
}
835829
}
836830
else
@@ -2483,7 +2477,7 @@ index_set_state_flags(Oid indexId, IndexStateFlagsAction action)
24832477
* IndexGetRelation: given an index's relation OID, get the OID of the
24842478
* relation it is an index on.Uses the system cache.
24852479
*/
2486-
staticOid
2480+
Oid
24872481
IndexGetRelation(OidindexId)
24882482
{
24892483
HeapTupletuple;

‎src/backend/catalog/pg_constraint.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,25 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
726726
heap_close(conRel,RowExclusiveLock);
727727
}
728728

729+
/*
730+
* get_constraint_relation_oids
731+
*Find the IDs of the relations to which a constraint refers.
732+
*/
733+
void
734+
get_constraint_relation_oids(Oidconstraint_oid,Oid*conrelid,Oid*confrelid)
735+
{
736+
HeapTupletup;
737+
Form_pg_constraintcon;
738+
739+
tup=SearchSysCache1(CONSTROID,ObjectIdGetDatum(constraint_oid));
740+
if (!HeapTupleIsValid(tup))/* should not happen */
741+
elog(ERROR,"cache lookup failed for constraint %u",constraint_oid);
742+
con= (Form_pg_constraint)GETSTRUCT(tup);
743+
*conrelid=con->conrelid;
744+
*confrelid=con->confrelid;
745+
ReleaseSysCache(tup);
746+
}
747+
729748
/*
730749
* GetConstraintByName
731750
*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
@@ -93,9 +93,8 @@ ExecRenameStmt(RenameStmt *stmt)
9393
{
9494
Oidrelid;
9595

96-
CheckRelationOwnership(stmt->relation, true);
97-
9896
relid=RangeVarGetRelid(stmt->relation, false);
97+
CheckRelationOwnership(relid, true);
9998

10099
switch (stmt->renameType)
101100
{
@@ -188,7 +187,6 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
188187
caseOBJECT_SEQUENCE:
189188
caseOBJECT_TABLE:
190189
caseOBJECT_VIEW:
191-
CheckRelationOwnership(stmt->relation, true);
192190
AlterTableNamespace(stmt->relation,stmt->newschema,
193191
stmt->objectType);
194192
break;

‎src/backend/commands/indexcmds.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ static bool relationHasPrimaryKey(Relation rel);
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 bool relationHasPrimaryKey(Relation rel);
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,
@@ -127,7 +128,6 @@ DefineIndex(RangeVar *heapRelation,
127128
{
128129
Oid*classObjectId;
129130
OidaccessMethodId;
130-
OidrelationId;
131131
OidnamespaceId;
132132
OidtablespaceId;
133133
List*indexColNames;
@@ -147,6 +147,7 @@ DefineIndex(RangeVar *heapRelation,
147147
intn_old_snapshots;
148148
LockRelIdheaprelid;
149149
LOCKTAGheaplocktag;
150+
LOCKMODElockmode;
150151
Snapshotsnapshot;
151152
inti;
152153

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

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

177182
relationId=RelationGetRelid(rel);
178183
namespaceId=RelationGetNamespace(rel);
@@ -183,7 +188,7 @@ DefineIndex(RangeVar *heapRelation,
183188
ereport(ERROR,
184189
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
185190
errmsg("\"%s\" is not a table",
186-
heapRelation->relname)));
191+
RelationGetRelationName(rel))));
187192

188193
/*
189194
* Don't try to CREATE INDEX on temp tables of other backends.
@@ -567,7 +572,7 @@ DefineIndex(RangeVar *heapRelation,
567572
*/
568573

569574
/* Open and lock the parent heap relation */
570-
rel=heap_openrv(heapRelation,ShareUpdateExclusiveLock);
575+
rel=heap_open(relationId,ShareUpdateExclusiveLock);
571576

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp