Skip to content

Commit e439bbe

Browse files
committed
Avoid integer overflow while sifting-up a heap in tuplesort.c.
If the number of tuples in the heap exceeds approximately INT_MAX/2, this loop's calculation "2*i+1" could overflow, resulting in a crash. Fix it by using unsigned int rather than int for the relevant local variables; that shouldn't cost anything extra on any popular hardware. Per bug #14722 from Sergey Koposov. Original patch by Sergey Koposov, modified by me per a suggestion from Heikki Linnakangas to use unsigned int not int64. Back-patch to 9.4, where tuplesort.c grew the ability to sort as many as INT_MAX tuples in-memory (commit 263865a). Discussion: https://postgr.es/m/20170629161637.1478.93109@wrigleys.postgresql.org
1 parent a94dd0c commit e439bbe

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

src/backend/utils/sort/tuplesort.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2729,20 +2729,25 @@ tuplesort_heap_siftup(Tuplesortstate *state, bool checkIndex)
27292729
{
27302730
SortTuple *memtuples = state->memtuples;
27312731
SortTuple *tuple;
2732-
int i,
2732+
unsigned int i,
27332733
n;
27342734

27352735
if (--state->memtupcount <= 0)
27362736
return;
27372737

27382738
CHECK_FOR_INTERRUPTS();
27392739

2740+
/*
2741+
* state->memtupcount is "int", but we use "unsigned int" for i, j, n.
2742+
* This prevents overflow in the "2 * i + 1" calculation, since at the top
2743+
* of the loop we must have i < n <= INT_MAX <= UINT_MAX/2.
2744+
*/
27402745
n = state->memtupcount;
27412746
tuple = &memtuples[n]; /* tuple that must be reinserted */
27422747
i = 0; /* i is where the "hole" is */
27432748
for (;;)
27442749
{
2745-
int j = 2 * i + 1;
2750+
unsigned int j = 2 * i + 1;
27462751

27472752
if (j >= n)
27482753
break;

0 commit comments

Comments
 (0)