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

Commitccc8194

Browse files
committed
Fix use-after-free in parallel_vacuum_reset_dead_items
parallel_vacuum_reset_dead_items used a local variable to hold apointer from the passed vacrel, purely as a shorthand. This pointerwas later freed and a new allocation was made and stored to thestruct. Then the local pointer was mistakenly referenced again.This apparently happened not to break anything since the freed chunkwould have been put on the context's freelist, so it was accidentallythe same pointer anyway, in which case the DSA handle was correctlyupdated. The minimal fix is to change two places so they accessdead_items through the vacrel. This coding style is a maintenancehazard, so while at it get rid of most other similar usages, whichwere inconsistently used anyway.Analysis and patch by Vallimaharajan G, with further defensive codingby meBackpath to v17, when TidStore came inDiscussion:https://postgr.es/m/1936493cc38.68cb2ef27266.7456585136086197135@zohocorp.com
1 parent7727049 commitccc8194

File tree

2 files changed

+9
-15
lines changed

2 files changed

+9
-15
lines changed

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

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -828,8 +828,6 @@ lazy_scan_heap(LVRelState *vacrel)
828828
next_fsm_block_to_vacuum=0;
829829
boolall_visible_according_to_vm;
830830

831-
TidStore*dead_items=vacrel->dead_items;
832-
VacDeadItemsInfo*dead_items_info=vacrel->dead_items_info;
833831
Buffervmbuffer=InvalidBuffer;
834832
constintinitprog_index[]= {
835833
PROGRESS_VACUUM_PHASE,
@@ -841,7 +839,7 @@ lazy_scan_heap(LVRelState *vacrel)
841839
/* Report that we're scanning the heap, advertising total # of blocks */
842840
initprog_val[0]=PROGRESS_VACUUM_PHASE_SCAN_HEAP;
843841
initprog_val[1]=rel_pages;
844-
initprog_val[2]=dead_items_info->max_bytes;
842+
initprog_val[2]=vacrel->dead_items_info->max_bytes;
845843
pgstat_progress_update_multi_param(3,initprog_index,initprog_val);
846844

847845
/* Initialize for the first heap_vac_scan_next_block() call */
@@ -884,7 +882,7 @@ lazy_scan_heap(LVRelState *vacrel)
884882
* dead_items TIDs, pause and do a cycle of vacuuming before we tackle
885883
* this page.
886884
*/
887-
if (TidStoreMemoryUsage(dead_items)>dead_items_info->max_bytes)
885+
if (TidStoreMemoryUsage(vacrel->dead_items)>vacrel->dead_items_info->max_bytes)
888886
{
889887
/*
890888
* Before beginning index vacuuming, we release any pin we may
@@ -1054,7 +1052,7 @@ lazy_scan_heap(LVRelState *vacrel)
10541052
* Do index vacuuming (call each index's ambulkdelete routine), then do
10551053
* related heap vacuuming
10561054
*/
1057-
if (dead_items_info->num_items>0)
1055+
if (vacrel->dead_items_info->num_items>0)
10581056
lazy_vacuum(vacrel);
10591057

10601058
/*
@@ -2895,19 +2893,18 @@ static void
28952893
dead_items_add(LVRelState*vacrel,BlockNumberblkno,OffsetNumber*offsets,
28962894
intnum_offsets)
28972895
{
2898-
TidStore*dead_items=vacrel->dead_items;
28992896
constintprog_index[2]= {
29002897
PROGRESS_VACUUM_NUM_DEAD_ITEM_IDS,
29012898
PROGRESS_VACUUM_DEAD_TUPLE_BYTES
29022899
};
29032900
int64prog_val[2];
29042901

2905-
TidStoreSetBlockOffsets(dead_items,blkno,offsets,num_offsets);
2902+
TidStoreSetBlockOffsets(vacrel->dead_items,blkno,offsets,num_offsets);
29062903
vacrel->dead_items_info->num_items+=num_offsets;
29072904

29082905
/* update the progress information */
29092906
prog_val[0]=vacrel->dead_items_info->num_items;
2910-
prog_val[1]=TidStoreMemoryUsage(dead_items);
2907+
prog_val[1]=TidStoreMemoryUsage(vacrel->dead_items);
29112908
pgstat_progress_update_multi_param(2,prog_index,prog_val);
29122909
}
29132910

@@ -2917,16 +2914,14 @@ dead_items_add(LVRelState *vacrel, BlockNumber blkno, OffsetNumber *offsets,
29172914
staticvoid
29182915
dead_items_reset(LVRelState*vacrel)
29192916
{
2920-
TidStore*dead_items=vacrel->dead_items;
2921-
29222917
if (ParallelVacuumIsActive(vacrel))
29232918
{
29242919
parallel_vacuum_reset_dead_items(vacrel->pvs);
29252920
return;
29262921
}
29272922

29282923
/* Recreate the tidstore with the same max_bytes limitation */
2929-
TidStoreDestroy(dead_items);
2924+
TidStoreDestroy(vacrel->dead_items);
29302925
vacrel->dead_items=TidStoreCreateLocal(vacrel->dead_items_info->max_bytes, true);
29312926

29322927
/* Reset the counter */

‎src/backend/commands/vacuumparallel.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -474,21 +474,20 @@ parallel_vacuum_get_dead_items(ParallelVacuumState *pvs, VacDeadItemsInfo **dead
474474
void
475475
parallel_vacuum_reset_dead_items(ParallelVacuumState*pvs)
476476
{
477-
TidStore*dead_items=pvs->dead_items;
478477
VacDeadItemsInfo*dead_items_info=&(pvs->shared->dead_items_info);
479478

480479
/*
481480
* Free the current tidstore and return allocated DSA segments to the
482481
* operating system. Then we recreate the tidstore with the same max_bytes
483482
* limitation we just used.
484483
*/
485-
TidStoreDestroy(dead_items);
484+
TidStoreDestroy(pvs->dead_items);
486485
pvs->dead_items=TidStoreCreateShared(dead_items_info->max_bytes,
487486
LWTRANCHE_PARALLEL_VACUUM_DSA);
488487

489488
/* Update the DSA pointer for dead_items to the new one */
490-
pvs->shared->dead_items_dsa_handle=dsa_get_handle(TidStoreGetDSA(dead_items));
491-
pvs->shared->dead_items_handle=TidStoreGetHandle(dead_items);
489+
pvs->shared->dead_items_dsa_handle=dsa_get_handle(TidStoreGetDSA(pvs->dead_items));
490+
pvs->shared->dead_items_handle=TidStoreGetHandle(pvs->dead_items);
492491

493492
/* Reset the counter */
494493
dead_items_info->num_items=0;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp