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

Commitc67c2e2

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 parent9fc1776 commitc67c2e2

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+
gotoerror;
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)

[8]ページ先頭

©2009-2025 Movatter.jp