Thread
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Fix reuse-after-free hazard in dead_items_reset
- 76613b539ac5 18.1 landed
- 3549ffb6afaf 17.7 landed
- 54ab74865147 19 (unreleased) landed
-
[Bug] Usage of stale dead_items pointer in parallel vacuum
Kevin Oommen Anish <kevin.o@zohocorp.com> — 2025-10-01T15:55:53Z
Hello Developers, We have discovered a bug in the dead_items_reset function in PG v17 specifically near the parallel_vacuum_reset_dead_items function() invocation. The bug is still prevalent in the latest version v18 as well. Although it was introduced in v17, it was detected while running the vacuum.sql regression tests which were introduced in PG v17.5. In dead_items_reset function, we destroy and recreate the shared TidStore by invoking the parallel_vacuum_reset_dead_items() function. However, after the reallocation, the vacrel->dead_items pointer is not updated to point to the newly allocated TidStore. As a result, the leader process continues to hold a pointer to the destroyed TidStore. As a result, subsequent calls by the leader process to dead_items_add() go through this stale pointer, resulting in a use-after-free. However this goes unnoticed since the freeing and reallocation of the shared TidStore (vacrel->pvs->dead_items) are so close to each other, that the AllocSet memory context always hands back the exact same chunk of memory that was freed previously, making the stale vacrel->dead_items pointer still appear valid even though it technically points to freed storage. This issue was reproduced while running the existing regression tests from vacuum.sql with our custom malloc allocator implementation. For your reference, we have previously shared our custom malloc allocator implementation in a separate bug fix. (message ID: mailto:1936493cc38.68cb2ef27266.7456585136086197135@zohocorp.com ).The corresponding crash backtrace is attached as well. Failed regression: CREATE TABLE pvactst2 (i INT) WITH (autovacuum_enabled = off); INSERT INTO pvactst2 SELECT generate_series(1, 1000); CREATE INDEX ON pvactst2 (i); CREATE INDEX ON pvactst2 (i); SET min_parallel_index_scan_size to 0; SET maintenance_work_mem TO 64; INSERT INTO pvactst2 SELECT generate_series(1, 1000); DELETE FROM pvactst2 WHERE i < 1000; VACUUM (PARALLEL 2) pvactst2; Please let me know if you have any questions or would like further details. Thanks & Regards, Kevin Oommen Anish Member Technical Staff ZOHO Corporation
-
Re: [Bug] Usage of stale dead_items pointer in parallel vacuum
Richard Guo <guofenglinux@gmail.com> — 2025-10-02T04:16:47Z
On Thu, Oct 2, 2025 at 12:56 AM Kevin Oommen Anish <kevin.o@zohocorp.com> wrote: > Failed regression: > CREATE TABLE pvactst2 (i INT) WITH (autovacuum_enabled = off); > INSERT INTO pvactst2 SELECT generate_series(1, 1000); > CREATE INDEX ON pvactst2 (i); > CREATE INDEX ON pvactst2 (i); > SET min_parallel_index_scan_size to 0; > SET maintenance_work_mem TO 64; > INSERT INTO pvactst2 SELECT generate_series(1, 1000); > DELETE FROM pvactst2 WHERE i < 1000; > VACUUM (PARALLEL 2) pvactst2; I can reproduce the issue and confirm that your patch fixes it. I didn't use your custom malloc allocator but instead applied a redundant palloc0 for TidStore in TidStoreCreateShared(), hoping to get a different chunk of memory (haha). @@ -212,6 +212,7 @@ TidStoreCreateShared(size_t max_bytes, int tranche_id) size_t dsa_init_size = DSA_DEFAULT_INIT_SEGMENT_SIZE; size_t dsa_max_size = DSA_MAX_SEGMENT_SIZE; + ts = palloc0(sizeof(TidStore)); ts = palloc0(sizeof(TidStore)); - Richard -
Re: [Bug] Usage of stale dead_items pointer in parallel vacuum
John Naylor <johncnaylorls@gmail.com> — 2025-10-02T05:09:47Z
On Thu, Oct 2, 2025 at 11:17 AM Richard Guo <guofenglinux@gmail.com> wrote: > I can reproduce the issue and confirm that your patch fixes it. I > didn't use your custom malloc allocator but instead applied a > redundant palloc0 for TidStore in TidStoreCreateShared(), hoping to > get a different chunk of memory (haha). I'm starting to wonder if we should have something similar to that allocator in core, which is actually here and not in the link upthread: https://www.postgresql.org/message-id/193261e2c4d.3dd3cd7c1842.871636075166132237@zohocorp.com -- John Naylor Amazon Web Services
-
Re: [Bug] Usage of stale dead_items pointer in parallel vacuum
Richard Guo <guofenglinux@gmail.com> — 2025-10-02T09:33:02Z
On Thu, Oct 2, 2025 at 2:09 PM John Naylor <johncnaylorls@gmail.com> wrote: > On Thu, Oct 2, 2025 at 11:17 AM Richard Guo <guofenglinux@gmail.com> wrote: > > I can reproduce the issue and confirm that your patch fixes it. I > > didn't use your custom malloc allocator but instead applied a > > redundant palloc0 for TidStore in TidStoreCreateShared(), hoping to > > get a different chunk of memory (haha). > I'm starting to wonder if we should have something similar to that > allocator in core, which is actually here and not in the link > upthread: +1. This issue is more like a reuse-after-free rather than a use-after-free, and it doesn't seem easy to detect with current tools. This kind of allocator seems to be quite useful -- it has helped catch at least two bugs in our code so far. - Richard
-
Re: [Bug] Usage of stale dead_items pointer in parallel vacuum
John Naylor <johncnaylorls@gmail.com> — 2025-10-03T09:28:54Z
On Wed, Oct 1, 2025 at 10:56 PM Kevin Oommen Anish <kevin.o@zohocorp.com> wrote: > We have discovered a bug in the dead_items_reset function in PG v17 specifically near the parallel_vacuum_reset_dead_items function() invocation. The bug is still prevalent in the latest version v18 as well. Although it was introduced in v17, it was detected while running the vacuum.sql regression tests which were introduced in PG v17.5. I've pushed your fix, thanks for the report! -- John Naylor Amazon Web Services