Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit17fd203

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 withmulti-gigabyte-sized query-texts files. It occurred to me that on32-bit platforms, there could be an issue with integer overflowof 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, butthis helps.2. Add a check to prevent extending the query-texts file tomore than MaxAllocHugeSize. If it got that big, qtext_load_filewould 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-bitarithmetic on all platforms. It appears possible that under duressthose multiplications could overflow 32 bits, yielding a falseconclusion that we need to garbage-collect the texts file, whichcould lead to repeatedly garbage-collecting after every hash tableinsertion.Per report from Bruno da Silva. I'm not convinced that theseissues fully explain his problem; there may be some other bug that'scontributing to the query-texts file becoming so large in the firstplace. But it did get that big, so#2 is a reasonable defense,and#3 could explain the reported performance difficulties.(See also commit8bbe4cb, 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.comDiscussion:https://postgr.es/m/5601D354.5000703@BlueTreble.com
1 parentd947a8b commit17fd203

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
@@ -385,7 +385,7 @@ _PG_init(void)
385385
&pgss_max,
386386
5000,
387387
100,
388-
INT_MAX,
388+
INT_MAX /2,
389389
PGC_POSTMASTER,
390390
0,
391391
NULL,
@@ -2060,6 +2060,18 @@ qtext_store(const char *query, int query_len,
20602060

20612061
*query_offset=off;
20622062

2063+
/*
2064+
* Don't allow the file to grow larger than what qtext_load_file can
2065+
* (theoretically) handle. This has been seen to be reachable on 32-bit
2066+
* platforms.
2067+
*/
2068+
if (unlikely(query_len >=MaxAllocHugeSize-off))
2069+
{
2070+
errno=EFBIG;/* not quite right, but it'll do */
2071+
fd=-1;
2072+
gotoerror;
2073+
}
2074+
20632075
/* Now write the data into the successfully-reserved part of the file */
20642076
fd=OpenTransientFile(PGSS_TEXT_FILE,O_RDWR |O_CREAT |PG_BINARY);
20652077
if (fd<0)
@@ -2245,8 +2257,14 @@ need_gc_qtexts(void)
22452257
SpinLockRelease(&s->mutex);
22462258
}
22472259

2248-
/* Don't proceed if file does not exceed 512 bytes per possible entry */
2249-
if (extent<512*pgss_max)
2260+
/*
2261+
* Don't proceed if file does not exceed 512 bytes per possible entry.
2262+
*
2263+
* Here and in the next test, 32-bit machines have overflow hazards if
2264+
* pgss_max and/or mean_query_len are large. Force the multiplications
2265+
* and comparisons to be done in uint64 arithmetic to forestall trouble.
2266+
*/
2267+
if ((uint64)extent< (uint64)512*pgss_max)
22502268
return false;
22512269

22522270
/*
@@ -2256,7 +2274,7 @@ need_gc_qtexts(void)
22562274
* query length in order to prevent garbage collection from thrashing
22572275
* uselessly.
22582276
*/
2259-
if (extent<pgss->mean_query_len*pgss_max*2)
2277+
if ((uint64)extent< (uint64)pgss->mean_query_len*pgss_max*2)
22602278
return false;
22612279

22622280
return true;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp