From badeb15ca1261a3681603ab7fe0a3898a640fdfc Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Tue, 18 Feb 2025 12:25:49 -0500
Subject: [PATCH v1 2/4] Harden brininsertcleanup against repeat calls.

Leaving an empty BrinInsertState struct linked in ii_AmCache
confuses both brininsertcleanup itself and brininsert, were that
to be called again.  We should fully remove it, instead.

This stops the crash reported in bug #18815.  I think it's fixing
the symptom rather than the root cause, but nonetheless there's
little argument for brininsertcleanup to be leaving an obviously
broken data structure behind.

Bug: #18815
Reported-by: Sergey Belyashov <sergey.belyashov@gmail.com>
Discussion: https://postgr.es/m/18815-2a0407cc7f40b327@postgresql.org
Backpatch-through: TBD
---
 src/backend/access/brin/brin.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c
index 4265687afa..60320440fc 100644
--- a/src/backend/access/brin/brin.c
+++ b/src/backend/access/brin/brin.c
@@ -511,16 +511,18 @@ brininsertcleanup(Relation index, IndexInfo *indexInfo)
 	BrinInsertState *bistate = (BrinInsertState *) indexInfo->ii_AmCache;
 
 	/* bail out if cache not initialized */
-	if (indexInfo->ii_AmCache == NULL)
+	if (bistate == NULL)
 		return;
 
+	/* do this first to avoid dangling pointer if we fail partway through */
+	indexInfo->ii_AmCache = NULL;
+
 	/*
 	 * Clean up the revmap. Note that the brinDesc has already been cleaned up
 	 * as part of its own memory context.
 	 */
 	brinRevmapTerminate(bistate->bis_rmAccess);
-	bistate->bis_rmAccess = NULL;
-	bistate->bis_desc = NULL;
+	pfree(bistate);
 }
 
 /*
-- 
2.43.5

