Types gbtreekey32 and gbtreekey16 aren't adequately aligned

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: pgsql-hackers(at)postgreSQL(dot)org
Subject: Types gbtreekey32 and gbtreekey16 aren't adequately aligned
Date: 2016-11-28 22:43:34
Message-ID: 31982.1480373014@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

contrib/btree_gist declares type gbtreekey32 without any particular
alignment spec, which means it defaults to 4-byte ("integer") alignment.
However, btree_interval.c supposes that it can map a pair of intervals
onto that storage. Since an interval contains a float8, that means we
end up trying to manipulate float8's that aren't double-aligned, causing
crashes on alignment-picky hardware.

I can replicate such a crash on my old HPPA box by doing this in
btree_gist's regression database (I'm just borrowing its interval
sample data):

contrib_regression=# create table ui (x text, a interval);
CREATE TABLE
contrib_regression=# insert into ui select null, a from intervaltmp ;
INSERT 0 612
contrib_regression=# insert into ui select '', a from intervaltmp ;
INSERT 0 612
contrib_regression=# insert into ui select 'q', a from intervaltmp ;
INSERT 0 612
contrib_regression=# insert into ui select 'qq', a from intervaltmp ;
INSERT 0 612
contrib_regression=# insert into ui select 'qqq', a from intervaltmp ;
INSERT 0 612
contrib_regression=# create index on ui using gist(x,a);
server closed the connection unexpectedly

The point of the text column of course is just to ensure that the index
contains gbtreekey32 entries that aren't maxaligned by virtue of
being at the front of their index tuple.

I failed to duplicate this crash on an old Apple PPC box, but it's
not 64-bit and I think the hardware is OK with doubles that are only
4-byte-aligned. PPC64 would likely be less happy.

The same problem applies to mapping float8 or int8 onto gbtreekey16.

contrib_regression=# create table foo (x text, a int8);
CREATE TABLE
contrib_regression=# insert into foo select null, a from int8tmp ;
INSERT 0 600
contrib_regression=# insert into foo select '', a from int8tmp ;
INSERT 0 600
contrib_regression=# insert into foo select 'x', a from int8tmp ;
INSERT 0 600
contrib_regression=# insert into foo select 'xx', a from int8tmp ;
INSERT 0 600
contrib_regression=# insert into foo select 'xxx', a from int8tmp ;
INSERT 0 600
contrib_regression=# create index on foo using gist(x,a);
server closed the connection unexpectedly

We could fix this easily by redeclaring gbtreekey32 and gbtreekey16
with alignment = double, but that would cause issues for existing
multicolumn gist indexes (and I'm not sure how ALTER EXTENSION
UPDATE could manage such a change). But the alternative of teaching
the code to avoid unaligned fetches seems messy and bug-prone.

Thoughts?

regards, tom lane

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2016-11-28 22:50:55 Re: PSQL commands: \quit_if, \quit_unless
Previous Message Alvaro Herrera 2016-11-28 22:34:33 Re: patch: function xmltable