Re: Fix uninitialized PruneFreezeResult in pruneheap and vacuumlazy

From: Feilong Meng <feelingmeng(at)foxmail(dot)com>
To: Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com>, Postgres hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Cc: Melanie Plageman <melanieplageman(at)gmail(dot)com>
Subject: Re: Fix uninitialized PruneFreezeResult in pruneheap and vacuumlazy
Date: 2025-12-11 10:17:39
Message-ID: tencent_F99BAF3F98799941EF31EEEE23E34A0B2F05@qq.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi Chao Li,Hackers,

&gt; PruneFreezeResult presult; <== here presult is not initialized

&gt; &nbsp; const PruneFreezeResult *presult, <== presult is a const pointer, so prune_freeze_setup won’t update its content
&gt; &nbsp; PruneState *prstate)
&gt; {
&gt; &nbsp; &nbsp; prstate-&gt;deadoffsets = (OffsetNumber *) presult-&gt;deadoffsets; <== presult-&gt;deadoffsets could be a random value
&gt; }
&gt; ```

&gt; Attached is a simple fix by just initializing presult in the first place with {0}.&nbsp;

&nbsp; &nbsp; Initializing ’presult‘ under my operating system is very effective.
&nbsp; &nbsp; I have tested the change, and "make check" passed.

Best regards!

Feilong&nbsp;Meng
feelingmeng(at)foxmail(dot)com

HighGo&nbsp;Software&nbsp;Co.,&nbsp;Ltd.

https://www.highgo.com/

Original


From: Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com&gt;
Date: 2025-12-11 12:02
To: Postgres hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org&gt;
Cc: Melanie Plageman <melanieplageman(at)gmail(dot)com&gt;
Subject: Fix uninitialized PruneFreezeResult in pruneheap and vacuumlazy

Hi Hackers,

While reviewing Melanie's patch [1], I found this bug where presult is not initialized. Let me explain the logic.

In the first place:
```
static int
lazy_scan_prune(LVRelState *vacrel,
Buffer buf,
BlockNumber blkno,
Page page,
Buffer vmbuffer,
bool all_visible_according_to_vm,
bool *has_lpdead_items,
bool *vm_page_frozen)
{
Relation rel = vacrel-&gt;rel;
PruneFreezeResult presult; <== here presult is not initialized

heap_page_prune_and_freeze(&amp;params,
&nbsp; &amp;presult, <== uninitialized presult is passed into&nbsp;heap_page_prune_and_freeze
&nbsp; &amp;vacrel-&gt;offnum,
&nbsp; &amp;vacrel-&gt;NewRelfrozenXid, &amp;vacrel-&gt;NewRelminMxid);
```

Then in&nbsp;heap_page_prune_and_freeze():
```
void
heap_page_prune_and_freeze(PruneFreezeParams *params,
&nbsp; PruneFreezeResult *presult,
&nbsp; OffsetNumber *off_loc,
&nbsp; TransactionId *new_relfrozen_xid,
&nbsp; MultiXactId *new_relmin_mxid)
{
Buffer buffer = params-&gt;buffer;
Page page = BufferGetPage(buffer);
PruneState prstate;
bool do_freeze;
bool do_prune;
bool do_hint_prune;
bool did_tuple_hint_fpi;
int64 fpi_before = pgWalUsage.wal_fpi;

/* Initialize prstate */
prune_freeze_setup(params,
&nbsp; new_relfrozen_xid, new_relmin_mxid,
&nbsp; presult, &amp;prstate); <== immediately pass&nbsp;uninitialized presult to&nbsp;prune_freeze_setup
```

Then in&nbsp;prune_freeze_setup():
```
static void
prune_freeze_setup(PruneFreezeParams *params,
&nbsp; TransactionId *new_relfrozen_xid,
&nbsp; MultiXactId *new_relmin_mxid,
&nbsp; const PruneFreezeResult *presult, <== presult is a const pointer, so&nbsp;prune_freeze_setup won’t update its content
&nbsp; PruneState *prstate)
{
&nbsp; &nbsp; prstate-&gt;deadoffsets = (OffsetNumber *) presult-&gt;deadoffsets; <==&nbsp;presult-&gt;deadoffsets could be a random value
}
```

Attached is a simple fix by just initializing presult in the first place with {0}.&nbsp;

[1] https://postgr.es/m/CAAKRu_bvQiesumRhgvbcym1T9Z9=ddGfUbi-dSNxLRc6JvL1-w@mail.gmail.com

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Ajit Awekar 2025-12-11 10:52:33 Re: Periodic authorization expiration checks using GoAway message
Previous Message Chao Li 2025-12-11 10:00:20 Docs: Standardize "cannot" usage in SGML source