radixtree: Fix crash when non-creator begins iteration over shared tree.
authorMasahiko Sawada <msawada@postgresql.org>
Thu, 6 Feb 2025 19:35:51 +0000 (11:35 -0800)
committerMasahiko Sawada <msawada@postgresql.org>
Thu, 6 Feb 2025 19:35:51 +0000 (11:35 -0800)
Previously, if a backend that attached to a shared tree attempted to
start iteration, it resulted in a crash. This commit resolves the
issue by ensuring iter_context is created in RT_ATTACH().

This fix applies only to v17, where radixtree.h was introduced. In the
master branch, this issue was separately resolved by 960013f2a1, which
eliminated the iter_context entirely.

Reviewed-by: John Naylor
Discussion: https://postgr.es/m/CAD21AoBB2U47V=F+wQRB1bERov_of5=BOZGaybjaV8FLQyqG3Q@mail.gmail.com

src/include/lib/radixtree.h

index 1301f3fee44deb1f5a67eadb9bc8384146755928..4cbadf4f5ec604caf563f6dc4801e5ffec60ae8d 100644 (file)
@@ -1902,6 +1902,7 @@ RT_ATTACH(dsa_area *dsa, RT_HANDLE handle)
    dsa_pointer control;
 
    tree = (RT_RADIX_TREE *) palloc0(sizeof(RT_RADIX_TREE));
+   tree->context = CurrentMemoryContext;
 
    /* Find the control object in shared memory */
    control = handle;
@@ -1910,6 +1911,14 @@ RT_ATTACH(dsa_area *dsa, RT_HANDLE handle)
    tree->ctl = (RT_RADIX_TREE_CONTROL *) dsa_get_address(dsa, control);
    Assert(tree->ctl->magic == RT_RADIX_TREE_MAGIC);
 
+   /*
+    * Create the iteration context so that the attached backend also can
+    * begin the iteration.
+    */
+   tree->iter_context = AllocSetContextCreate(CurrentMemoryContext,
+                                              RT_STR(RT_PREFIX) "_radix_tree iter context",
+                                              ALLOCSET_SMALL_SIZES);
+
    return tree;
 }
 
@@ -1917,6 +1926,7 @@ RT_SCOPE void
 RT_DETACH(RT_RADIX_TREE * tree)
 {
    Assert(tree->ctl->magic == RT_RADIX_TREE_MAGIC);
+   MemoryContextDelete(tree->iter_context);
    pfree(tree);
 }