aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Frost <sfrost@snowman.net>2013-07-14 16:43:23 -0400
committerStephen Frost <sfrost@snowman.net>2013-07-14 16:43:23 -0400
commit89c09fe02d9aa77aea28525b97229f61f1d5e471 (patch)
tree03276162e821ce38fc69911be56860cdcb213d24
parent129e9dd1a2527a5a69d9761f11991a1857bcd91d (diff)
downloadpostgresql-89c09fe02d9aa77aea28525b97229f61f1d5e471.tar.gz
postgresql-89c09fe02d9aa77aea28525b97229f61f1d5e471.zip
Ensure 64bit arithmetic when calculating tapeSpace
In tuplesort.c:inittapes(), we calculate tapeSpace by first figuring out how many 'tapes' we can use (maxTapes) and then multiplying the result by the tape buffer overhead for each. Unfortunately, when we are on a system with an 8-byte long, we allow work_mem to be larger than 2GB and that allows maxTapes to be large enough that the 32bit arithmetic can overflow when multiplied against the buffer overhead. When this overflow happens, we end up adding the overflow to the amount of space available, causing the amount of memory allocated to be larger than work_mem. Note that to reach this point, you have to set work mem to at least 24GB and be sorting a set which is at least that size. Given that a user who can set work_mem to 24GB could also set it even higher, if they were looking to run the system out of memory, this isn't considered a security issue. This overflow risk was found by the Coverity scanner. Back-patch to all supported branches, as this issue has existed since before 8.4.
-rw-r--r--src/backend/utils/sort/tuplesort.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index d5a2003e5b8..1f55478e024 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -1693,7 +1693,7 @@ inittapes(Tuplesortstate *state)
* account for tuple space, so we don't care if LACKMEM becomes
* inaccurate.)
*/
- tapeSpace = maxTapes * TAPE_BUFFER_OVERHEAD;
+ tapeSpace = (long) maxTapes * TAPE_BUFFER_OVERHEAD;
if (tapeSpace + GetMemoryChunkSpace(state->memtuples) < state->allowedMem)
USEMEM(state, tapeSpace);