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

Commite1e0a4d

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 parent30b1c40 commite1e0a4d

File tree

18 files changed

+234
-157
lines changed

18 files changed

+234
-157
lines changed

‎src/backend/bootstrap/bootparse.y‎

Lines changed: 15 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"
@@ -282,6 +283,7 @@ Boot_DeclareIndexStmt:
282283
XDECLAREINDEXboot_identoidspecONboot_identUSINGboot_identLPARENboot_index_paramsRPAREN
283284
{
284285
IndexStmt *stmt = makeNode(IndexStmt);
286+
OidrelationId;
285287

286288
do_start();
287289

@@ -303,7 +305,12 @@ Boot_DeclareIndexStmt:
303305
stmt->initdeferred =false;
304306
stmt->concurrent =false;
305307

306-
DefineIndex(stmt,
308+
/* locks and races need not concern us in bootstrap mode*/
309+
relationId = RangeVarGetRelid(stmt->relation, NoLock,
310+
false);
311+
312+
DefineIndex(relationId,
313+
stmt,
307314
$4,
308315
false,
309316
false,
@@ -317,6 +324,7 @@ Boot_DeclareUniqueIndexStmt:
317324
XDECLAREUNIQUEINDEXboot_identoidspecONboot_identUSINGboot_identLPARENboot_index_paramsRPAREN
318325
{
319326
IndexStmt *stmt = makeNode(IndexStmt);
327+
OidrelationId;
320328

321329
do_start();
322330

@@ -338,7 +346,12 @@ Boot_DeclareUniqueIndexStmt:
338346
stmt->initdeferred =false;
339347
stmt->concurrent =false;
340348

341-
DefineIndex(stmt,
349+
/* locks and races need not concern us in bootstrap mode*/
350+
relationId = RangeVarGetRelid(stmt->relation, NoLock,
351+
false);
352+
353+
DefineIndex(relationId,
354+
stmt,
342355
$5,
343356
false,
344357
false,

‎src/backend/catalog/index.c‎

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,18 +1214,13 @@ index_constraint_create(Relation heapRelation,
12141214
*/
12151215
if (deferrable)
12161216
{
1217-
RangeVar*heapRel;
12181217
CreateTrigStmt*trigger;
12191218

1220-
heapRel=makeRangeVar(get_namespace_name(namespaceId),
1221-
pstrdup(RelationGetRelationName(heapRelation)),
1222-
-1);
1223-
12241219
trigger=makeNode(CreateTrigStmt);
12251220
trigger->trigname= (constraintType==CONSTRAINT_PRIMARY) ?
12261221
"PK_ConstraintTrigger" :
12271222
"Unique_ConstraintTrigger";
1228-
trigger->relation=heapRel;
1223+
trigger->relation=NULL;
12291224
trigger->funcname=SystemFuncName("unique_key_recheck");
12301225
trigger->args=NIL;
12311226
trigger->row= true;
@@ -1238,7 +1233,8 @@ index_constraint_create(Relation heapRelation,
12381233
trigger->initdeferred=initdeferred;
12391234
trigger->constrrel=NULL;
12401235

1241-
(void)CreateTrigger(trigger,NULL,conOid,indexRelationId, true);
1236+
(void)CreateTrigger(trigger,NULL,RelationGetRelid(heapRelation),
1237+
InvalidOid,conOid,indexRelationId, true);
12421238
}
12431239

12441240
/*

‎src/backend/catalog/pg_constraint.c‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,25 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
751751
heap_close(conRel,RowExclusiveLock);
752752
}
753753

754+
/*
755+
* get_constraint_relation_oids
756+
*Find the IDs of the relations to which a constraint refers.
757+
*/
758+
void
759+
get_constraint_relation_oids(Oidconstraint_oid,Oid*conrelid,Oid*confrelid)
760+
{
761+
HeapTupletup;
762+
Form_pg_constraintcon;
763+
764+
tup=SearchSysCache1(CONSTROID,ObjectIdGetDatum(constraint_oid));
765+
if (!HeapTupleIsValid(tup))/* should not happen */
766+
elog(ERROR,"cache lookup failed for constraint %u",constraint_oid);
767+
con= (Form_pg_constraint)GETSTRUCT(tup);
768+
*conrelid=con->conrelid;
769+
*confrelid=con->confrelid;
770+
ReleaseSysCache(tup);
771+
}
772+
754773
/*
755774
* get_relation_constraint_oid
756775
*Find a constraint on the specified relation with the specified name.

‎src/backend/commands/indexcmds.c‎

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ static void RangeVarCallbackForReindexIndex(const RangeVar *relation,
112112
*/
113113
bool
114114
CheckIndexCompatible(OidoldId,
115-
RangeVar*heapRelation,
116115
char*accessMethodName,
117116
List*attributeList,
118117
List*exclusionOpNames)
@@ -140,7 +139,7 @@ CheckIndexCompatible(Oid oldId,
140139
Datumd;
141140

142141
/* Caller should already have the relation locked in some way. */
143-
relationId=RangeVarGetRelid(heapRelation,NoLock, false);
142+
relationId=IndexGetRelation(oldId, false);
144143

145144
/*
146145
* We can pretend isconstraint = false unconditionally. It only serves to
@@ -280,6 +279,8 @@ CheckIndexCompatible(Oid oldId,
280279
* DefineIndex
281280
*Creates a new index.
282281
*
282+
* 'relationId': the OID of the heap relation on which the index is to be
283+
*created
283284
* 'stmt': IndexStmt describing the properties of the new index.
284285
* 'indexRelationId': normally InvalidOid, but during bootstrap can be
285286
*nonzero to specify a preselected OID for the index.
@@ -293,7 +294,8 @@ CheckIndexCompatible(Oid oldId,
293294
* Returns the OID of the created index.
294295
*/
295296
Oid
296-
DefineIndex(IndexStmt*stmt,
297+
DefineIndex(OidrelationId,
298+
IndexStmt*stmt,
297299
OidindexRelationId,
298300
boolis_alter_table,
299301
boolcheck_rights,
@@ -306,7 +308,6 @@ DefineIndex(IndexStmt *stmt,
306308
Oid*collationObjectId;
307309
Oid*classObjectId;
308310
OidaccessMethodId;
309-
OidrelationId;
310311
OidnamespaceId;
311312
OidtablespaceId;
312313
List*indexColNames;
@@ -326,6 +327,7 @@ DefineIndex(IndexStmt *stmt,
326327
intn_old_snapshots;
327328
LockRelIdheaprelid;
328329
LOCKTAGheaplocktag;
330+
LOCKMODElockmode;
329331
Snapshotsnapshot;
330332
inti;
331333

@@ -344,14 +346,18 @@ DefineIndex(IndexStmt *stmt,
344346
INDEX_MAX_KEYS)));
345347

346348
/*
347-
* Open heap relation, acquire a suitable lock on it, remember its OID
348-
*
349349
* Only SELECT ... FOR UPDATE/SHARE are allowed while doing a standard
350350
* index build; but for concurrent builds we allow INSERT/UPDATE/DELETE
351351
* (but not VACUUM).
352+
*
353+
* NB: Caller is responsible for making sure that relationId refers
354+
* to the relation on which the index should be built; except in bootstrap
355+
* mode, this will typically require the caller to have already locked
356+
* the relation. To avoid lock upgrade hazards, that lock should be at
357+
* least as strong as the one we take here.
352358
*/
353-
rel=heap_openrv(stmt->relation,
354-
(stmt->concurrent ?ShareUpdateExclusiveLock :ShareLock));
359+
lockmode=stmt->concurrent ?ShareUpdateExclusiveLock :ShareLock;
360+
rel=heap_open(relationId,lockmode);
355361

356362
relationId=RelationGetRelid(rel);
357363
namespaceId=RelationGetNamespace(rel);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp