On 11/2/16 1:54 PM, Tom Lane wrote:
> I think the right thing is likely to be to copy the presented bytea
> into a palloc'd (and therefore properly aligned) buffer.  And not
> just in this one function.

Does the attached look reasonable?

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
>From 086c603016de5018a8baddc88a8932472e0fcd1e Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Thu, 3 Nov 2016 12:00:00 -0400
Subject: [PATCH] pageinspect: Fix unaligned struct access in GIN functions

The raw page data that is passed into the functions will not be aligned
at 8-byte boundaries.  Casting that to a struct and accessing int64
fields will result in unaligned access.  On most platforms, you get away
with it, but it will result on a crash on pickier platforms such as ia64
and sparc64.
---
 contrib/pageinspect/ginfuncs.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/contrib/pageinspect/ginfuncs.c b/contrib/pageinspect/ginfuncs.c
index 145e2ce..660d236 100644
--- a/contrib/pageinspect/ginfuncs.c
+++ b/contrib/pageinspect/ginfuncs.c
@@ -51,7 +51,10 @@ gin_metapage_info(PG_FUNCTION_ARGS)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("input page too small (%d bytes)", raw_page_size)));
-	page = VARDATA(raw_page);
+
+	/* make a copy so that the page is properly aligned for struct access */
+	page = palloc(raw_page_size);
+	memcpy(page, VARDATA(raw_page), raw_page_size);
 
 	opaq = (GinPageOpaque) PageGetSpecialPointer(page);
 	if (opaq->flags != GIN_META)
@@ -115,7 +118,10 @@ gin_page_opaque_info(PG_FUNCTION_ARGS)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("input page too small (%d bytes)", raw_page_size)));
-	page = VARDATA(raw_page);
+
+	/* make a copy so that the page is properly aligned for struct access */
+	page = palloc(raw_page_size);
+	memcpy(page, VARDATA(raw_page), raw_page_size);
 
 	opaq = (GinPageOpaque) PageGetSpecialPointer(page);
 
@@ -195,7 +201,10 @@ gin_leafpage_items(PG_FUNCTION_ARGS)
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				  errmsg("input page too small (%d bytes)", raw_page_size)));
-		page = VARDATA(raw_page);
+
+		/* make a copy so that the page is properly aligned for struct access */
+		page = palloc(raw_page_size);
+		memcpy(page, VARDATA(raw_page), raw_page_size);
 
 		if (PageGetSpecialSize(page) != MAXALIGN(sizeof(GinPageOpaqueData)))
 			ereport(ERROR,
-- 
2.10.2

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to