Skip to content

Commit 84ad68d

Browse files
committed
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.
1 parent f2e6a2c commit 84ad68d

File tree

1 file changed

+24
-22
lines changed

1 file changed

+24
-22
lines changed

contrib/pageinspect/ginfuncs.c

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,31 @@ PG_FUNCTION_INFO_V1(gin_metapage_info);
2828
PG_FUNCTION_INFO_V1(gin_page_opaque_info);
2929
PG_FUNCTION_INFO_V1(gin_leafpage_items);
3030

31+
32+
static Page
33+
get_page_from_raw(bytea *raw_page)
34+
{
35+
int raw_page_size;
36+
Page page;
37+
38+
raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
39+
if (raw_page_size < BLCKSZ)
40+
ereport(ERROR,
41+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
42+
errmsg("input page too small (%d bytes)", raw_page_size)));
43+
44+
/* make a copy so that the page is properly aligned for struct access */
45+
page = palloc(raw_page_size);
46+
memcpy(page, VARDATA(raw_page), raw_page_size);
47+
48+
return page;
49+
}
50+
51+
3152
Datum
3253
gin_metapage_info(PG_FUNCTION_ARGS)
3354
{
3455
bytea *raw_page = PG_GETARG_BYTEA_P(0);
35-
int raw_page_size;
3656
TupleDesc tupdesc;
3757
Page page;
3858
GinPageOpaque opaq;
@@ -46,12 +66,7 @@ gin_metapage_info(PG_FUNCTION_ARGS)
4666
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4767
(errmsg("must be superuser to use raw page functions"))));
4868

49-
raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
50-
if (raw_page_size < BLCKSZ)
51-
ereport(ERROR,
52-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
53-
errmsg("input page too small (%d bytes)", raw_page_size)));
54-
page = VARDATA(raw_page);
69+
page = get_page_from_raw(raw_page);
5570

5671
opaq = (GinPageOpaque) PageGetSpecialPointer(page);
5772
if (opaq->flags != GIN_META)
@@ -94,7 +109,6 @@ Datum
94109
gin_page_opaque_info(PG_FUNCTION_ARGS)
95110
{
96111
bytea *raw_page = PG_GETARG_BYTEA_P(0);
97-
int raw_page_size;
98112
TupleDesc tupdesc;
99113
Page page;
100114
GinPageOpaque opaq;
@@ -110,12 +124,7 @@ gin_page_opaque_info(PG_FUNCTION_ARGS)
110124
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
111125
(errmsg("must be superuser to use raw page functions"))));
112126

113-
raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
114-
if (raw_page_size < BLCKSZ)
115-
ereport(ERROR,
116-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
117-
errmsg("input page too small (%d bytes)", raw_page_size)));
118-
page = VARDATA(raw_page);
127+
page = get_page_from_raw(raw_page);
119128

120129
opaq = (GinPageOpaque) PageGetSpecialPointer(page);
121130

@@ -173,7 +182,6 @@ Datum
173182
gin_leafpage_items(PG_FUNCTION_ARGS)
174183
{
175184
bytea *raw_page = PG_GETARG_BYTEA_P(0);
176-
int raw_page_size;
177185
FuncCallContext *fctx;
178186
gin_leafpage_items_state *inter_call_data;
179187

@@ -182,20 +190,14 @@ gin_leafpage_items(PG_FUNCTION_ARGS)
182190
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
183191
(errmsg("must be superuser to use raw page functions"))));
184192

185-
raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
186-
187193
if (SRF_IS_FIRSTCALL())
188194
{
189195
TupleDesc tupdesc;
190196
MemoryContext mctx;
191197
Page page;
192198
GinPageOpaque opaq;
193199

194-
if (raw_page_size < BLCKSZ)
195-
ereport(ERROR,
196-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
197-
errmsg("input page too small (%d bytes)", raw_page_size)));
198-
page = VARDATA(raw_page);
200+
page = get_page_from_raw(raw_page);
199201

200202
if (PageGetSpecialSize(page) != MAXALIGN(sizeof(GinPageOpaqueData)))
201203
ereport(ERROR,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy