Re: [HACKERS] doPickSplit stack buffer overflow in XLogInsert?

2014-06-05 Thread Heikki Linnakangas

On 05/06/2014 07:36 PM, Andres Freund wrote:

On 2014-05-06 13:33:01 +0300, Heikki Linnakangas wrote:

On 03/31/2014 09:08 PM, Robert Haas wrote:

On Wed, Mar 26, 2014 at 9:45 PM, Peter Geoghegan p...@heroku.com wrote:

On Wed, Nov 27, 2013 at 9:10 AM, Noah Misch n...@leadboat.com wrote:

The threat is that rounding the read size up to the next MAXALIGN would cross
into an unreadable memory page, resulting in a SIGSEGV.  Every palloc chunk
has MAXALIGN'd size under the hood, so the excess read of toDelete cannot
cause a SIGSEGV.  For a stack variable, it depends on the ABI.  I'm not aware
of an ABI where the four bytes past the end of this stack variable could be
unreadable, which is not to claim I'm well-read on the topic.  We should fix
this in due course on code hygiene grounds, but I would not back-patch it.


Attached patch silences the Invalid read of size n complaints of
Valgrind. I agree with your general thoughts around backpatching. Note
that the patch addresses a distinct complaint from Kevin's, as
Valgrind doesn't take issue with the invalid reads past the end of
spgxlogPickSplit variables on the stack.


Is the needless zeroing this patch introduces apt to cause a
performance problem?

This function is actually pretty wacky.  If we're stuffing bytes with
undefined contents into the WAL record, maybe the answer isn't to
force the contents of those bytes to be defined, but rather to elide
them from the WAL record.


Agreed. I propose the attached, which removes the MAXALIGNs. It's not
suitable for backpatching, though, as it changes the format of the WAL
record.

y
Not knowing anything about spgist this looks sane to me.


Since we did a catversion bump anyway, I revisited this. Committed an 
expanded version of the patch I posted earlier. I went through all the 
SP-GiST WAL record types and removed the alignment requirements of 
tuples from all of them. Most of them didn't have a problem because the 
structs happened to have suitable alignment by accident, but seems best 
to not rely on that, for the sake of consistency and robustness if the 
structs are modified later.


I ran this through my testing tool that compares page image on master 
and standby after every WAL record replay, with full_page_writes on and 
off, and found no errors.



Do we need a
backpatchable solution given that we seem to agree that these bugs
aren't likely to cause harm?


I don't think we do.

- Heikki


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


Re: [HACKERS] doPickSplit stack buffer overflow in XLogInsert?

2014-05-06 Thread Heikki Linnakangas

On 03/31/2014 09:08 PM, Robert Haas wrote:

On Wed, Mar 26, 2014 at 9:45 PM, Peter Geoghegan p...@heroku.com wrote:

On Wed, Nov 27, 2013 at 9:10 AM, Noah Misch n...@leadboat.com wrote:

The threat is that rounding the read size up to the next MAXALIGN would cross
into an unreadable memory page, resulting in a SIGSEGV.  Every palloc chunk
has MAXALIGN'd size under the hood, so the excess read of toDelete cannot
cause a SIGSEGV.  For a stack variable, it depends on the ABI.  I'm not aware
of an ABI where the four bytes past the end of this stack variable could be
unreadable, which is not to claim I'm well-read on the topic.  We should fix
this in due course on code hygiene grounds, but I would not back-patch it.


Attached patch silences the Invalid read of size n complaints of
Valgrind. I agree with your general thoughts around backpatching. Note
that the patch addresses a distinct complaint from Kevin's, as
Valgrind doesn't take issue with the invalid reads past the end of
spgxlogPickSplit variables on the stack.


Is the needless zeroing this patch introduces apt to cause a
performance problem?

This function is actually pretty wacky.  If we're stuffing bytes with
undefined contents into the WAL record, maybe the answer isn't to
force the contents of those bytes to be defined, but rather to elide
them from the WAL record.


Agreed. I propose the attached, which removes the MAXALIGNs. It's not 
suitable for backpatching, though, as it changes the format of the WAL 
record.


- Heikki
diff --git a/src/backend/access/spgist/spgdoinsert.c b/src/backend/access/spgist/spgdoinsert.c
index 48f32cd..ff403ef 100644
--- a/src/backend/access/spgist/spgdoinsert.c
+++ b/src/backend/access/spgist/spgdoinsert.c
@@ -533,9 +533,9 @@ moveLeafs(Relation index, SpGistState *state,
 	{
 		XLogRecPtr	recptr;
 
-		ACCEPT_RDATA_DATA(xlrec, MAXALIGN(sizeof(xlrec)), 0);
-		ACCEPT_RDATA_DATA(toDelete, MAXALIGN(sizeof(OffsetNumber) * nDelete), 1);
-		ACCEPT_RDATA_DATA(toInsert, MAXALIGN(sizeof(OffsetNumber) * nInsert), 2);
+		ACCEPT_RDATA_DATA(xlrec, SizeOfSpgxlogMoveLeafs, 0);
+		ACCEPT_RDATA_DATA(toDelete, sizeof(OffsetNumber) * nDelete, 1);
+		ACCEPT_RDATA_DATA(toInsert, sizeof(OffsetNumber) * nInsert, 2);
 		ACCEPT_RDATA_DATA(leafdata, leafptr - leafdata, 3);
 		ACCEPT_RDATA_BUFFER(current-buffer, 4);
 		ACCEPT_RDATA_BUFFER(nbuf, 5);
@@ -1116,7 +1116,7 @@ doPickSplit(Relation index, SpGistState *state,
 
 	leafdata = leafptr = (char *) palloc(totalLeafSizes);
 
-	ACCEPT_RDATA_DATA(xlrec, MAXALIGN(sizeof(xlrec)), 0);
+	ACCEPT_RDATA_DATA(xlrec, SizeOfSpgxlogPickSplit, 0);
 	ACCEPT_RDATA_DATA(innerTuple, innerTuple-size, 1);
 	nRdata = 2;
 
@@ -1152,7 +1152,7 @@ doPickSplit(Relation index, SpGistState *state,
 		{
 			xlrec.nDelete = nToDelete;
 			ACCEPT_RDATA_DATA(toDelete,
-			  MAXALIGN(sizeof(OffsetNumber) * nToDelete),
+			  sizeof(OffsetNumber) * nToDelete,
 			  nRdata);
 			nRdata++;
 			ACCEPT_RDATA_BUFFER(current-buffer, nRdata);
@@ -1251,13 +1251,9 @@ doPickSplit(Relation index, SpGistState *state,
 	}
 
 	xlrec.nInsert = nToInsert;
-	ACCEPT_RDATA_DATA(toInsert,
-	  MAXALIGN(sizeof(OffsetNumber) * nToInsert),
-	  nRdata);
+	ACCEPT_RDATA_DATA(toInsert, sizeof(OffsetNumber) * nToInsert, nRdata);
 	nRdata++;
-	ACCEPT_RDATA_DATA(leafPageSelect,
-	  MAXALIGN(sizeof(uint8) * nToInsert),
-	  nRdata);
+	ACCEPT_RDATA_DATA(leafPageSelect, sizeof(uint8) * nToInsert, nRdata);
 	nRdata++;
 	ACCEPT_RDATA_DATA(leafdata, leafptr - leafdata, nRdata);
 	nRdata++;
diff --git a/src/backend/access/spgist/spgxlog.c b/src/backend/access/spgist/spgxlog.c
index 1689324..cd6a4b2 100644
--- a/src/backend/access/spgist/spgxlog.c
+++ b/src/backend/access/spgist/spgxlog.c
@@ -205,7 +205,7 @@ static void
 spgRedoMoveLeafs(XLogRecPtr lsn, XLogRecord *record)
 {
 	char	   *ptr = XLogRecGetData(record);
-	spgxlogMoveLeafs *xldata = (spgxlogMoveLeafs *) ptr;
+	spgxlogMoveLeafs *xldata;
 	SpGistState state;
 	OffsetNumber *toDelete;
 	OffsetNumber *toInsert;
@@ -213,18 +213,19 @@ spgRedoMoveLeafs(XLogRecPtr lsn, XLogRecord *record)
 	Buffer		buffer;
 	Page		page;
 
-	fillFakeState(state, xldata-stateSrc);
-
+	xldata = (spgxlogMoveLeafs *) ptr;
 	nInsert = xldata-replaceDead ? 1 : xldata-nMoves + 1;
 
-	ptr += MAXALIGN(sizeof(spgxlogMoveLeafs));
+	ptr += SizeOfSpgxlogMoveLeafs;
 	toDelete = (OffsetNumber *) ptr;
-	ptr += MAXALIGN(sizeof(OffsetNumber) * xldata-nMoves);
+	ptr += sizeof(OffsetNumber) * xldata-nMoves;
 	toInsert = (OffsetNumber *) ptr;
-	ptr += MAXALIGN(sizeof(OffsetNumber) * nInsert);
+	ptr += sizeof(OffsetNumber) * nInsert;
 
 	/* now ptr points to the list of leaf tuples */
 
+	fillFakeState(state, xldata-stateSrc);
+
 	/*
 	 * In normal operation we would have all three pages (source, dest, and
 	 * parent) locked simultaneously; but in WAL replay it should be safe to
@@ -252,10 +253,16 @@ spgRedoMoveLeafs(XLogRecPtr lsn, XLogRecord *record)
 
 for (i = 0; i  nInsert; i++)
 {
-	SpGistLeafTuple lt = 

Re: [HACKERS] doPickSplit stack buffer overflow in XLogInsert?

2014-05-06 Thread Andres Freund
On 2014-05-06 13:33:01 +0300, Heikki Linnakangas wrote:
 On 03/31/2014 09:08 PM, Robert Haas wrote:
 On Wed, Mar 26, 2014 at 9:45 PM, Peter Geoghegan p...@heroku.com wrote:
 On Wed, Nov 27, 2013 at 9:10 AM, Noah Misch n...@leadboat.com wrote:
 The threat is that rounding the read size up to the next MAXALIGN would 
 cross
 into an unreadable memory page, resulting in a SIGSEGV.  Every palloc chunk
 has MAXALIGN'd size under the hood, so the excess read of toDelete cannot
 cause a SIGSEGV.  For a stack variable, it depends on the ABI.  I'm not 
 aware
 of an ABI where the four bytes past the end of this stack variable could be
 unreadable, which is not to claim I'm well-read on the topic.  We should 
 fix
 this in due course on code hygiene grounds, but I would not back-patch it.
 
 Attached patch silences the Invalid read of size n complaints of
 Valgrind. I agree with your general thoughts around backpatching. Note
 that the patch addresses a distinct complaint from Kevin's, as
 Valgrind doesn't take issue with the invalid reads past the end of
 spgxlogPickSplit variables on the stack.
 
 Is the needless zeroing this patch introduces apt to cause a
 performance problem?
 
 This function is actually pretty wacky.  If we're stuffing bytes with
 undefined contents into the WAL record, maybe the answer isn't to
 force the contents of those bytes to be defined, but rather to elide
 them from the WAL record.
 
 Agreed. I propose the attached, which removes the MAXALIGNs. It's not
 suitable for backpatching, though, as it changes the format of the WAL
 record.

Not knowing anything about spgist this looks sane to me. Do we need a
backpatchable solution given that we seem to agree that these bugs
aren't likely to cause harm?

Greetings,

Andres Freund

-- 
 Andres Freund http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training  Services


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


Re: [HACKERS] doPickSplit stack buffer overflow in XLogInsert?

2014-05-05 Thread Andres Freund
Hi,

We really should fix this one of these days.

On 2014-03-26 18:45:54 -0700, Peter Geoghegan wrote:
 Attached patch silences the Invalid read of size n complaints of
 Valgrind. I agree with your general thoughts around backpatching. Note
 that the patch addresses a distinct complaint from Kevin's, as
 Valgrind doesn't take issue with the invalid reads past the end of
 spgxlogPickSplit variables on the stack.

I don't think that's entirely sufficient. The local spgxlogPickSplit
xlrec;/spgxlogMoveLeafs xlrec; variables are also inserted while
MAXLIGNing their size. That's slightly harder to fix :(. I don't have a
better idea than also allocating them dynamically :(

Greetings,

Andres Freund

-- 
 Andres Freund http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training  Services


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


Re: [HACKERS] doPickSplit stack buffer overflow in XLogInsert?

2014-03-31 Thread Robert Haas
On Wed, Mar 26, 2014 at 9:45 PM, Peter Geoghegan p...@heroku.com wrote:
 On Wed, Nov 27, 2013 at 9:10 AM, Noah Misch n...@leadboat.com wrote:
 The threat is that rounding the read size up to the next MAXALIGN would cross
 into an unreadable memory page, resulting in a SIGSEGV.  Every palloc chunk
 has MAXALIGN'd size under the hood, so the excess read of toDelete cannot
 cause a SIGSEGV.  For a stack variable, it depends on the ABI.  I'm not aware
 of an ABI where the four bytes past the end of this stack variable could be
 unreadable, which is not to claim I'm well-read on the topic.  We should fix
 this in due course on code hygiene grounds, but I would not back-patch it.

 Attached patch silences the Invalid read of size n complaints of
 Valgrind. I agree with your general thoughts around backpatching. Note
 that the patch addresses a distinct complaint from Kevin's, as
 Valgrind doesn't take issue with the invalid reads past the end of
 spgxlogPickSplit variables on the stack.

Is the needless zeroing this patch introduces apt to cause a
performance problem?

This function is actually pretty wacky.  If we're stuffing bytes with
undefined contents into the WAL record, maybe the answer isn't to
force the contents of those bytes to be defined, but rather to elide
them from the WAL record.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


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


Re: [HACKERS] doPickSplit stack buffer overflow in XLogInsert?

2014-03-26 Thread Peter Geoghegan
On Wed, Nov 27, 2013 at 9:10 AM, Noah Misch n...@leadboat.com wrote:
 The threat is that rounding the read size up to the next MAXALIGN would cross
 into an unreadable memory page, resulting in a SIGSEGV.  Every palloc chunk
 has MAXALIGN'd size under the hood, so the excess read of toDelete cannot
 cause a SIGSEGV.  For a stack variable, it depends on the ABI.  I'm not aware
 of an ABI where the four bytes past the end of this stack variable could be
 unreadable, which is not to claim I'm well-read on the topic.  We should fix
 this in due course on code hygiene grounds, but I would not back-patch it.

Attached patch silences the Invalid read of size n complaints of
Valgrind. I agree with your general thoughts around backpatching. Note
that the patch addresses a distinct complaint from Kevin's, as
Valgrind doesn't take issue with the invalid reads past the end of
spgxlogPickSplit variables on the stack.

-- 
Peter Geoghegan
*** a/src/backend/access/spgist/spgdoinsert.c
--- b/src/backend/access/spgist/spgdoinsert.c
*** moveLeafs(Relation index, SpGistState *s
*** 412,419 
  
  	/* Locate the tuples to be moved, and count up the space needed */
  	i = PageGetMaxOffsetNumber(current-page);
! 	toDelete = (OffsetNumber *) palloc(sizeof(OffsetNumber) * i);
! 	toInsert = (OffsetNumber *) palloc(sizeof(OffsetNumber) * (i + 1));
  
  	size = newLeafTuple-size + sizeof(ItemIdData);
  
--- 412,419 
  
  	/* Locate the tuples to be moved, and count up the space needed */
  	i = PageGetMaxOffsetNumber(current-page);
! 	toDelete = (OffsetNumber *) palloc0(MAXALIGN(sizeof(OffsetNumber) * i));
! 	toInsert = (OffsetNumber *) palloc0(MAXALIGN(sizeof(OffsetNumber) * (i + 1)));
  
  	size = newLeafTuple-size + sizeof(ItemIdData);
  
*** doPickSplit(Relation index, SpGistState
*** 722,731 
  	n = max + 1;
  	in.datums = (Datum *) palloc(sizeof(Datum) * n);
  	heapPtrs = (ItemPointerData *) palloc(sizeof(ItemPointerData) * n);
! 	toDelete = (OffsetNumber *) palloc(sizeof(OffsetNumber) * n);
! 	toInsert = (OffsetNumber *) palloc(sizeof(OffsetNumber) * n);
  	newLeafs = (SpGistLeafTuple *) palloc(sizeof(SpGistLeafTuple) * n);
! 	leafPageSelect = (uint8 *) palloc(sizeof(uint8) * n);
  
  	xlrec.node = index-rd_node;
  	STORE_STATE(state, xlrec.stateSrc);
--- 722,731 
  	n = max + 1;
  	in.datums = (Datum *) palloc(sizeof(Datum) * n);
  	heapPtrs = (ItemPointerData *) palloc(sizeof(ItemPointerData) * n);
! 	toDelete = (OffsetNumber *) palloc0(MAXALIGN(sizeof(OffsetNumber) * n));
! 	toInsert = (OffsetNumber *) palloc0(MAXALIGN(sizeof(OffsetNumber) * n));
  	newLeafs = (SpGistLeafTuple *) palloc(sizeof(SpGistLeafTuple) * n);
! 	leafPageSelect = (uint8 *) palloc0(MAXALIGN(sizeof(uint8) * n));
  
  	xlrec.node = index-rd_node;
  	STORE_STATE(state, xlrec.stateSrc);

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


Re: [HACKERS] doPickSplit stack buffer overflow in XLogInsert?

2013-11-27 Thread Kevin Grittner
Andres Freund and...@2ndquadrant.com wrote:
 On 2013-11-26 14:14:38 -0800, Kevin Grittner wrote:

 I happened to build in a shell that was still set up for the clang
 address sanitizer, and got the attached report.  On a rerun it was
 repeatable.  XLogInsert() seems to read past the end of a variable
 allocated on the stack in doPickSplit(). I haven't tried to analyze
 it past that, since this part of the code is unfamiliar to me.

 Yea, I've seen that one before as well and planned to report it at some
 point. The reason is the MAXALIGN()s in ACCEPT_RDATA_DATA(). That rounds
 up to 8byte boundaries, while we've e.g. only added 2bytes of slop to
 toDelete.

Have you established whether having the CRC calculation read past
the end of the buffer can cause problems on recovery or standby
systems?  Should we try to get this fixed by Monday?

--
Kevin Grittner
EDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


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


Re: [HACKERS] doPickSplit stack buffer overflow in XLogInsert?

2013-11-27 Thread Noah Misch
On Wed, Nov 27, 2013 at 06:23:38AM -0800, Kevin Grittner wrote:
 Andres Freund and...@2ndquadrant.com wrote:
  On 2013-11-26 14:14:38 -0800, Kevin Grittner wrote:
 
  I happened to build in a shell that was still set up for the clang
  address sanitizer, and got the attached report.  On a rerun it was

(Kevin, I saw no attachment.)

  repeatable.  XLogInsert() seems to read past the end of a variable
  allocated on the stack in doPickSplit(). I haven't tried to analyze
  it past that, since this part of the code is unfamiliar to me.
 
  Yea, I've seen that one before as well and planned to report it at some
  point. The reason is the MAXALIGN()s in ACCEPT_RDATA_DATA(). That rounds
  up to 8byte boundaries, while we've e.g. only added 2bytes of slop to
  toDelete.
 
 Have you established whether having the CRC calculation read past
 the end of the buffer can cause problems on recovery or standby
 systems?  Should we try to get this fixed by Monday?

The threat is that rounding the read size up to the next MAXALIGN would cross
into an unreadable memory page, resulting in a SIGSEGV.  Every palloc chunk
has MAXALIGN'd size under the hood, so the excess read of toDelete cannot
cause a SIGSEGV.  For a stack variable, it depends on the ABI.  I'm not aware
of an ABI where the four bytes past the end of this stack variable could be
unreadable, which is not to claim I'm well-read on the topic.  We should fix
this in due course on code hygiene grounds, but I would not back-patch it.

-- 
Noah Misch
EnterpriseDB http://www.enterprisedb.com


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


Re: [HACKERS] doPickSplit stack buffer overflow in XLogInsert?

2013-11-27 Thread Kevin Grittner
Noah Misch n...@leadboat.com wrote:

 (Kevin, I saw no attachment.)

Apologies.  Trying again.

 The threat is that rounding the read size up to the next MAXALIGN
 would cross into an unreadable memory page, resulting in a
 SIGSEGV.  Every palloc chunk has MAXALIGN'd size under the hood,
 so the excess read of toDelete cannot cause a SIGSEGV.  For a
 stack variable, it depends on the ABI.  I'm not aware of an ABI
 where the four bytes past the end of this stack variable could be
 unreadable, which is not to claim I'm well-read on the topic.  We
 should fix this in due course on code hygiene grounds, but I
 would not back-patch it.

If you're sure.  I hadn't worked through the code, but had two
concerns (neither of which was about a SEGSEGV):

(1)  That multiple MAXALIGNs of shorter values could push the
structure into overlap with the next thing on the stack, allowing
one or the other to get stepped on.

(2)  That the CRC calculation might picking up uninitialized data
which was not actually going to match what was used during
recovery, leading to end of recovery on replay.

If you are confident that neither of these is a real risk, I'll
relax about this.

--
Kevin Grittner
EDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company=
==7232==ERROR: AddressSanitizer: stack-buffer-overflow on address 
0x7fffbcb2e834 at pc 0xef0335 bp 0x7fffbcb29b30 sp 0x7fffbcb29b28
READ of size 1 at 0x7fffbcb2e834 thread T0
#0 0xef0334 in XLogInsert 
/home/kgrittn/pg/master/src/backend/access/transam/xlog.c:1040
#1 0xd53792 in doPickSplit 
/home/kgrittn/pg/master/src/backend/access/spgist/spgdoinsert.c:1391
#2 0xd0d9f1 in spgdoinsert 
/home/kgrittn/pg/master/src/backend/access/spgist/spgdoinsert.c:2008
#3 0xcbb4d1 in spginsert 
/home/kgrittn/pg/master/src/backend/access/spgist/spginsert.c:238
#4 0x46f9de3 in FunctionCall6Coll 
/home/kgrittn/pg/master/src/backend/utils/fmgr/fmgr.c:1436
#5 0xad43fb in index_insert 
/home/kgrittn/pg/master/src/backend/access/index/indexam.c:223
#6 0x2122fcd in ExecInsertIndexTuples 
/home/kgrittn/pg/master/src/backend/executor/execUtils.c:1104
#7 0x228413f in ExecInsert 
/home/kgrittn/pg/master/src/backend/executor/nodeModifyTable.c:274
#8 0x227fba8 in ExecModifyTable 
/home/kgrittn/pg/master/src/backend/executor/nodeModifyTable.c:1014
#9 0x2026b03 in ExecProcNode 
/home/kgrittn/pg/master/src/backend/executor/execProcnode.c:377
#10 0x1fef534 in ExecutePlan 
/home/kgrittn/pg/master/src/backend/executor/execMain.c:1474
#11 0x1fee488 in standard_ExecutorRun 
/home/kgrittn/pg/master/src/backend/executor/execMain.c:308
#12 0x1fec7e9 in ExecutorRun 
/home/kgrittn/pg/master/src/backend/executor/execMain.c:256
#13 0x34f05ab in ProcessQuery 
/home/kgrittn/pg/master/src/backend/tcop/pquery.c:185
#14 0x34e8c3a in PortalRunMulti 
/home/kgrittn/pg/master/src/backend/tcop/pquery.c:1279
#15 0x34e1b9c in PortalRun 
/home/kgrittn/pg/master/src/backend/tcop/pquery.c:816
#16 0x34b6721 in exec_simple_query 
/home/kgrittn/pg/master/src/backend/tcop/postgres.c:1054
#17 0x34b1420 in PostgresMain 
/home/kgrittn/pg/master/src/backend/tcop/postgres.c:3998
#18 0x2f1f925 in BackendRun 
/home/kgrittn/pg/master/src/backend/postmaster/postmaster.c:4085
#19 0x2f1b830 in BackendStartup 
/home/kgrittn/pg/master/src/backend/postmaster/postmaster.c:3774
#20 0x2efcc96 in ServerLoop 
/home/kgrittn/pg/master/src/backend/postmaster/postmaster.c:1585
#21 0x2ef13ee in PostmasterMain 
/home/kgrittn/pg/master/src/backend/postmaster/postmaster.c:1240
#22 0x24dc3c3 in main /home/kgrittn/pg/master/src/backend/main/main.c:196
#23 0x2b89d526e76c in __libc_start_main 
/build/buildd/eglibc-2.15/csu/libc-start.c:226
#24 0x4dc3cc in _start ??:?

Address 0x7fffbcb2e834 is located in stack of thread T0 at offset 2644 in frame
#0 0xd2b5ef in doPickSplit 
/home/kgrittn/pg/master/src/backend/access/spgist/spgdoinsert.c:680

  This frame has 57 object(s):
[32, 40) ''
[96, 104) ''
[160, 168) ''
[224, 232) ''
[288, 296) ''
[352, 356) ''
[416, 417) ''
[480, 481) ''
[544, 545) 'insertedNew'
[608, 632) 'in'
[672, 720) 'out'
[768, 776) 'procinfo'
[832, 833) 'includeNew'
[896, 900) 'i'
[960, 964) 'max'
[1024, 1028) 'n'
[1088, 1096) 'innerTuple'
[1152, 1160) 'node'
[1216, 1224) 'nodes'
[1280, 1284) 'newInnerBuffer'
[1344, 1348) 'newLeafBuffer'
[1408, 1416) 'heapPtrs'
[1472, 1480) 'leafPageSelect'
[1536, 1544) 'leafSizes'
[1600, 1608) 'toDelete'
[1664, 1672) 'toInsert'
[1728, 1730) 'redirectTuplePos'
[1792, 1796) 'startOffsets'
[1856, 1864) 'newLeafs'
[1920, 1924) 'spaceToDelete'
[1984, 1988) 'currentFreeSpace'
[2048, 2052) 'totalLeafSizes'
[2112, 2113) 'allTheSame'
[2176, 2496) 'rdata'
[2528, 2532) 'nRdata'
[2592, 2644) 'xlrec' == Memory access 

Re: [HACKERS] doPickSplit stack buffer overflow in XLogInsert?

2013-11-27 Thread Noah Misch
On Wed, Nov 27, 2013 at 11:38:23AM -0800, Kevin Grittner wrote:
 Noah Misch n...@leadboat.com wrote:
  The threat is that rounding the read size up to the next MAXALIGN
  would cross into an unreadable memory page, resulting in a
  SIGSEGV.  Every palloc chunk has MAXALIGN'd size under the hood,
  so the excess read of toDelete cannot cause a SIGSEGV.  For a
  stack variable, it depends on the ABI.  I'm not aware of an ABI
  where the four bytes past the end of this stack variable could be
  unreadable, which is not to claim I'm well-read on the topic.  We
  should fix this in due course on code hygiene grounds, but I
  would not back-patch it.
 
 If you're sure.  I hadn't worked through the code, but had two
 concerns (neither of which was about a SEGSEGV):
 
 (1)  That multiple MAXALIGNs of shorter values could push the
 structure into overlap with the next thing on the stack, allowing
 one or the other to get stepped on.

These are out-of-bounds reads only, not writes.  Also, the excess doesn't
accumulate that way; the code reads beyond any particular stack variable or
palloc chunk by no more than 7 bytes.

 (2)  That the CRC calculation might picking up uninitialized data
 which was not actually going to match what was used during
 recovery, leading to end of recovery on replay.

The CRC calculation does pick up unspecified bytes, but we copy those same
bytes into the actual WAL record.  The effect is similar to that of
unspecified pad bytes in the middle of xlrec structures.

 If you are confident that neither of these is a real risk, I'll
 relax about this.

If there is a real risk, I'm not seeing it.

-- 
Noah Misch
EnterpriseDB http://www.enterprisedb.com


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


Re: [HACKERS] doPickSplit stack buffer overflow in XLogInsert?

2013-11-27 Thread Andres Freund
On 2013-11-27 15:29:24 -0500, Noah Misch wrote:
  If you are confident that neither of these is a real risk, I'll
  relax about this.
 
 If there is a real risk, I'm not seeing it.

Me neither.

Greetings,

Andres Freund

-- 
 Andres Freund http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training  Services


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


Re: [HACKERS] doPickSplit stack buffer overflow in XLogInsert?

2013-11-27 Thread Peter Eisentraut
On 11/26/13, 5:14 PM, Kevin Grittner wrote:
 I happened to build in a shell that was still set up for the clang
 address sanitizer, and got the attached report.  On a rerun it was
 repeatable.  XLogInsert() seems to read past the end of a variable
 allocated on the stack in doPickSplit(). I haven't tried to analyze
 it past that, since this part of the code is unfamiliar to me.

I also see that.  It only happens in 64-bit builds.


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


[HACKERS] doPickSplit stack buffer overflow in XLogInsert?

2013-11-26 Thread Kevin Grittner
I happened to build in a shell that was still set up for the clang
address sanitizer, and got the attached report.  On a rerun it was
repeatable.  XLogInsert() seems to read past the end of a variable
allocated on the stack in doPickSplit(). I haven't tried to analyze
it past that, since this part of the code is unfamiliar to me.

--
Kevin Grittner
EDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


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


Re: [HACKERS] doPickSplit stack buffer overflow in XLogInsert?

2013-11-26 Thread Andres Freund
On 2013-11-26 14:14:38 -0800, Kevin Grittner wrote:
 I happened to build in a shell that was still set up for the clang
 address sanitizer, and got the attached report.  On a rerun it was
 repeatable.  XLogInsert() seems to read past the end of a variable
 allocated on the stack in doPickSplit(). I haven't tried to analyze
 it past that, since this part of the code is unfamiliar to me.

Yea, I've seen that one before as well and planned to report it at some
point. The reason is the MAXALIGN()s in ACCEPT_RDATA_DATA(). That rounds
up to 8byte boundaries, while we've e.g. only added 2bytes of slop to
toDelete.


Greetings,

Andres Freund

-- 
 Andres Freund http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training  Services


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