From e13ac5586c49c77f301329b79bd7e8f489d0e66f Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Tue, 17 May 2016 17:01:18 -0400
Subject: [PATCH] Avoid possible crash in contrib/bloom's blendscan().

It's possible to begin and end an indexscan without ever calling
amrescan.  contrib/bloom, unlike every other index AM, allocated
its "scan->opaque" storage at amrescan time, and thus would crash
in amendscan if amrescan hadn't been called.  We could fix this
by putting in a null-pointer check in blendscan, but I see no very
good reason why contrib/bloom should march to its own drummer in
this respect.  Let's move that initialization to blbeginscan
instead.  Per report from Jeff Janes.
---
 contrib/bloom/blscan.c | 26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/contrib/bloom/blscan.c b/contrib/bloom/blscan.c
index fc82f543738..aebf32a8d2f 100644
--- a/contrib/bloom/blscan.c
+++ b/contrib/bloom/blscan.c
@@ -29,9 +29,16 @@ IndexScanDesc
 blbeginscan(Relation r, int nkeys, int norderbys)
 {
 	IndexScanDesc scan;
+	BloomScanOpaque so;
 
 	scan = RelationGetIndexScan(r, nkeys, norderbys);
 
+	so = (BloomScanOpaque) palloc(sizeof(BloomScanOpaqueData));
+	initBloomState(&so->state, scan->indexRelation);
+	so->sign = NULL;
+
+	scan->opaque = so;
+
 	return scan;
 }
 
@@ -42,23 +49,10 @@ void
 blrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
 		 ScanKey orderbys, int norderbys)
 {
-	BloomScanOpaque so;
-
-	so = (BloomScanOpaque) scan->opaque;
-
-	if (so == NULL)
-	{
-		/* if called from blbeginscan */
-		so = (BloomScanOpaque) palloc(sizeof(BloomScanOpaqueData));
-		initBloomState(&so->state, scan->indexRelation);
-		scan->opaque = so;
+	BloomScanOpaque so = (BloomScanOpaque) scan->opaque;
 
-	}
-	else
-	{
-		if (so->sign)
-			pfree(so->sign);
-	}
+	if (so->sign)
+		pfree(so->sign);
 	so->sign = NULL;
 
 	if (scankey && scan->numberOfKeys > 0)
-- 
GitLab