Skip to content

Commit c67c2e2

Browse files
committed
Be more wary about 32-bit integer overflow in pg_stat_statements.
We've heard a couple of reports of people having trouble with multi-gigabyte-sized query-texts files. It occurred to me that on 32-bit platforms, there could be an issue with integer overflow of calculations associated with the total query text size. Address that with several changes: 1. Limit pg_stat_statements.max to INT_MAX / 2 not INT_MAX. The hashtable code will bound it to that anyway unless "long" is 64 bits. We still need overflow guards on its use, but this helps. 2. Add a check to prevent extending the query-texts file to more than MaxAllocHugeSize. If it got that big, qtext_load_file would certainly fail, so there's not much point in allowing it. Without this, we'd need to consider whether extent, query_offset, and related variables shouldn't be off_t not size_t. 3. Adjust the comparisons in need_gc_qtexts() to be done in 64-bit arithmetic on all platforms. It appears possible that under duress those multiplications could overflow 32 bits, yielding a false conclusion that we need to garbage-collect the texts file, which could lead to repeatedly garbage-collecting after every hash table insertion. Per report from Bruno da Silva. I'm not convinced that these issues fully explain his problem; there may be some other bug that's contributing to the query-texts file becoming so large in the first place. But it did get that big, so #2 is a reasonable defense, and #3 could explain the reported performance difficulties. (See also commit 8bbe4cb, which addressed some related bugs. The second Discussion: link is the thread that led up to that.) This issue is old, and is primarily a problem for old platforms, so back-patch. Discussion: https://postgr.es/m/CAB+Nuk93fL1Q9eLOCotvLP07g7RAv4vbdrkm0cVQohDVMpAb9A@mail.gmail.com Discussion: https://postgr.es/m/5601D354.5000703@BlueTreble.com
1 parent 9fc1776 commit c67c2e2

File tree

1 file changed

+22
-4
lines changed

1 file changed

+22
-4
lines changed

contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ _PG_init(void)
397397
&pgss_max,
398398
5000,
399399
100,
400-
INT_MAX,
400+
INT_MAX / 2,
401401
PGC_POSTMASTER,
402402
0,
403403
NULL,
@@ -2086,6 +2086,18 @@ qtext_store(const char *query, int query_len,
20862086

20872087
*query_offset = off;
20882088

2089+
/*
2090+
* Don't allow the file to grow larger than what qtext_load_file can
2091+
* (theoretically) handle. This has been seen to be reachable on 32-bit
2092+
* platforms.
2093+
*/
2094+
if (unlikely(query_len >= MaxAllocHugeSize - off))
2095+
{
2096+
errno = EFBIG; /* not quite right, but it'll do */
2097+
fd = -1;
2098+
goto error;
2099+
}
2100+
20892101
/* Now write the data into the successfully-reserved part of the file */
20902102
fd = OpenTransientFile(PGSS_TEXT_FILE, O_RDWR | O_CREAT | PG_BINARY);
20912103
if (fd < 0)
@@ -2271,8 +2283,14 @@ need_gc_qtexts(void)
22712283
SpinLockRelease(&s->mutex);
22722284
}
22732285

2274-
/* Don't proceed if file does not exceed 512 bytes per possible entry */
2275-
if (extent < 512 * pgss_max)
2286+
/*
2287+
* Don't proceed if file does not exceed 512 bytes per possible entry.
2288+
*
2289+
* Here and in the next test, 32-bit machines have overflow hazards if
2290+
* pgss_max and/or mean_query_len are large. Force the multiplications
2291+
* and comparisons to be done in uint64 arithmetic to forestall trouble.
2292+
*/
2293+
if ((uint64) extent < (uint64) 512 * pgss_max)
22762294
return false;
22772295

22782296
/*
@@ -2282,7 +2300,7 @@ need_gc_qtexts(void)
22822300
* query length in order to prevent garbage collection from thrashing
22832301
* uselessly.
22842302
*/
2285-
if (extent < pgss->mean_query_len * pgss_max * 2)
2303+
if ((uint64) extent < (uint64) pgss->mean_query_len * pgss_max * 2)
22862304
return false;
22872305

22882306
return true;

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