| From: | Michael Paquier <michael(at)paquier(dot)xyz> |
|---|---|
| To: | Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com> |
| Cc: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: Fix unsafe PlannedStmt access in pg_stat_statements |
| Date: | 2026-05-12 03:30:53 |
| Message-ID: | agKe7cS_I-60GlpD@paquier.xyz |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Mon, May 11, 2026 at 04:11:41PM +0800, Chao Li wrote:
> On May 11, 2026, at 16:07, Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com> wrote:
>> In pgss_ProcessUtility(), there is this comment:
>> ```
>> /*
>> * CAUTION: do not access the *pstmt data structure again below here.
>> * If it was a ROLLBACK or similar, that data structure may have been
>> * freed. We must copy everything we still need into local variables,
>> * which we did above.
>> *
>> * For the same reason, we can't risk restoring pstmt->queryId to its
>> * former value, which'd otherwise be a good idea.
>> */
>> ```
>>
>> The attached patch fixes this by saving pstmt->planOrigin,
>> following the same pattern already used for queryId, stmt_location,
>> and stmt_len.
Yeah, you are right. This code should save the planOrigin but it does
not do so.
This is also pointing at a second issue that is not addressed by your
patch: there is no coverage for the assumption of this comment, or we
would have known about this issue when 3357471cf9f5 was committed.
Running the regression tests of PGSS with valgrind enabled leads to no
reports.
And that's where things got hairy on my side because it took me a
few hours before finding a case where I was able to get the following
report, where a PlannedStmt can get freed while we are in the hook
path:
==28059== Invalid read of size 4
==28059== at 0x165E42DF: pgss_ProcessUtility (pg_stat_statements.c:1200)
==28059== by 0x158AFCD: ProcessUtility (utility.c:524)
==28059== by 0x1587F3B: PortalRunUtility (pquery.c:1149)
==28059== by 0x15877E9: FillPortalStore (pquery.c:1022)
This has come down to the extended protocol and a ROLLBACK inside a
CALL procedure. The internal ROLLBACK is able to free the PlannedStmt
in pgss_ProcessUtility() in this case, after two executions.
> Oops! Forgot the attachment.
No problem.
All that said, I am attaching an updated version of the patch, for
posterity. I'll apply that in a bit with your fix and the test on
HEAD, after more checks.
--
Michael
| Attachment | Content-Type | Size |
|---|---|---|
| 0001-pg_stat_statements-Fix-potential-use-after-free-of-P.patch | text/plain | 3.5 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | John Naylor | 2026-05-12 03:38:40 | Re: First draft of PG 19 release notes |
| Previous Message | Robert Treat | 2026-05-12 02:34:47 | Re: First draft of PG 19 release notes |