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

Commit57fe246

Browse files
committed
Fix reference-after-free when waiting for another xact due to constraint.
If an insertion or update had to wait for another transaction to finish,because there was another insertion with conflicting key in progress,we would pass a just-free'd item pointer to XactLockTableWait().All calls to XactLockTableWait() and MultiXactIdWait() had similar issues.Some passed a pointer to a buffer in the buffer cache, after alreadyreleasing the lock. The call in EvalPlanQualFetch had already released thepin too. All but the call in execUtils.c would merely lead to reporting abogus ctid, however (or an assertion failure, if enabled).All the callers that passed HeapTuple->t_data->t_ctid were slightly bogusanyway: if the tuple was updated (again) in the same transaction, its ctidfield would point to the next tuple in the chain, not the tuple itself.Backpatch to 9.4, where the 'ctid' argument to XactLockTableWait was added(in commitf88d4cf)
1 parent370b3a4 commit57fe246

File tree

4 files changed

+14
-12
lines changed

4 files changed

+14
-12
lines changed

‎src/backend/access/heap/heapam.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2717,7 +2717,7 @@ heap_delete(Relation relation, ItemPointer tid,
27172717
{
27182718
/* wait for multixact */
27192719
MultiXactIdWait((MultiXactId)xwait,MultiXactStatusUpdate,infomask,
2720-
relation,&tp.t_data->t_ctid,XLTW_Delete,
2720+
relation,&(tp.t_self),XLTW_Delete,
27212721
NULL);
27222722
LockBuffer(buffer,BUFFER_LOCK_EXCLUSIVE);
27232723

@@ -2744,7 +2744,7 @@ heap_delete(Relation relation, ItemPointer tid,
27442744
else
27452745
{
27462746
/* wait for regular transaction to end */
2747-
XactLockTableWait(xwait,relation,&tp.t_data->t_ctid,XLTW_Delete);
2747+
XactLockTableWait(xwait,relation,&(tp.t_self),XLTW_Delete);
27482748
LockBuffer(buffer,BUFFER_LOCK_EXCLUSIVE);
27492749

27502750
/*
@@ -3261,7 +3261,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
32613261

32623262
/* wait for multixact */
32633263
MultiXactIdWait((MultiXactId)xwait,mxact_status,infomask,
3264-
relation,&oldtup.t_data->t_ctid,XLTW_Update,
3264+
relation,&oldtup.t_self,XLTW_Update,
32653265
&remain);
32663266
LockBuffer(buffer,BUFFER_LOCK_EXCLUSIVE);
32673267

@@ -3341,7 +3341,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
33413341
*/
33423342
heap_acquire_tuplock(relation,&(oldtup.t_self),*lockmode,
33433343
LockWaitBlock,&have_tuple_lock);
3344-
XactLockTableWait(xwait,relation,&oldtup.t_data->t_ctid,
3344+
XactLockTableWait(xwait,relation,&oldtup.t_self,
33453345
XLTW_Update);
33463346
LockBuffer(buffer,BUFFER_LOCK_EXCLUSIVE);
33473347

@@ -4365,7 +4365,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
43654365
{
43664366
caseLockWaitBlock:
43674367
MultiXactIdWait((MultiXactId)xwait,status,infomask,
4368-
relation,&tuple->t_data->t_ctid,XLTW_Lock,NULL);
4368+
relation,&tuple->t_self,XLTW_Lock,NULL);
43694369
break;
43704370
caseLockWaitSkip:
43714371
if (!ConditionalMultiXactIdWait((MultiXactId)xwait,
@@ -4437,7 +4437,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
44374437
switch (wait_policy)
44384438
{
44394439
caseLockWaitBlock:
4440-
XactLockTableWait(xwait,relation,&tuple->t_data->t_ctid,
4440+
XactLockTableWait(xwait,relation,&tuple->t_self,
44414441
XLTW_Lock);
44424442
break;
44434443
caseLockWaitSkip:
@@ -5181,7 +5181,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid,
51815181
{
51825182
LockBuffer(buf,BUFFER_LOCK_UNLOCK);
51835183
XactLockTableWait(members[i].xid,rel,
5184-
&mytup.t_data->t_ctid,
5184+
&mytup.t_self,
51855185
XLTW_LockUpdated);
51865186
pfree(members);
51875187
gotol4;
@@ -5242,7 +5242,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid,
52425242
if (needwait)
52435243
{
52445244
LockBuffer(buf,BUFFER_LOCK_UNLOCK);
5245-
XactLockTableWait(rawxmax,rel,&mytup.t_data->t_ctid,
5245+
XactLockTableWait(rawxmax,rel,&mytup.t_self,
52465246
XLTW_LockUpdated);
52475247
gotol4;
52485248
}

‎src/backend/catalog/index.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2328,7 +2328,7 @@ IndexBuildHeapRangeScan(Relation heapRelation,
23282328
*/
23292329
LockBuffer(scan->rs_cbuf,BUFFER_LOCK_UNLOCK);
23302330
XactLockTableWait(xwait,heapRelation,
2331-
&heapTuple->t_data->t_ctid,
2331+
&heapTuple->t_self,
23322332
XLTW_InsertIndexUnique);
23332333
CHECK_FOR_INTERRUPTS();
23342334
gotorecheck;
@@ -2377,7 +2377,7 @@ IndexBuildHeapRangeScan(Relation heapRelation,
23772377
*/
23782378
LockBuffer(scan->rs_cbuf,BUFFER_LOCK_UNLOCK);
23792379
XactLockTableWait(xwait,heapRelation,
2380-
&heapTuple->t_data->t_ctid,
2380+
&heapTuple->t_self,
23812381
XLTW_InsertIndexUnique);
23822382
CHECK_FOR_INTERRUPTS();
23832383
gotorecheck;

‎src/backend/executor/execMain.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2118,7 +2118,7 @@ EvalPlanQualFetch(EState *estate, Relation relation, int lockmode,
21182118
{
21192119
caseLockWaitBlock:
21202120
XactLockTableWait(SnapshotDirty.xmax,
2121-
relation,&tuple.t_data->t_ctid,
2121+
relation,&tuple.t_self,
21222122
XLTW_FetchUpdated);
21232123
break;
21242124
caseLockWaitSkip:

‎src/backend/executor/execUtils.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1245,6 +1245,7 @@ check_exclusion_constraint(Relation heap, Relation index, IndexInfo *indexInfo,
12451245
ForwardScanDirection))!=NULL)
12461246
{
12471247
TransactionIdxwait;
1248+
ItemPointerDatactid_wait;
12481249
Datumexisting_values[INDEX_MAX_KEYS];
12491250
boolexisting_isnull[INDEX_MAX_KEYS];
12501251
char*error_new;
@@ -1306,8 +1307,9 @@ check_exclusion_constraint(Relation heap, Relation index, IndexInfo *indexInfo,
13061307

13071308
if (TransactionIdIsValid(xwait))
13081309
{
1310+
ctid_wait=tup->t_data->t_ctid;
13091311
index_endscan(index_scan);
1310-
XactLockTableWait(xwait,heap,&tup->t_data->t_ctid,
1312+
XactLockTableWait(xwait,heap,&ctid_wait,
13111313
XLTW_RecheckExclusionConstr);
13121314
gotoretry;
13131315
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp