0001-pg_stat_statements-Fix-potential-use-after-free-of-P.patch
text/plain
Filename: 0001-pg_stat_statements-Fix-potential-use-after-free-of-P.patch
Type: text/plain
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch 0001
Subject: pg_stat_statements: Fix potential use-after-free of PlannedStmt
| File | + | − |
|---|---|---|
| contrib/pg_stat_statements/expected/plancache.out | 38 | 0 |
| contrib/pg_stat_statements/pg_stat_statements.c | 2 | 1 |
| contrib/pg_stat_statements/sql/plancache.sql | 19 | 0 |
From 19281d8708facd17cd65a9ab07dd7b775496a5c9 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Tue, 12 May 2026 12:24:52 +0900
Subject: [PATCH] pg_stat_statements: Fix potential use-after-free of
PlannedStmt
Blahblahblah.
Author: Chao Li
Co-authored-by: Michael Paquier
Discussion: https://postgr.es/m/
---
.../pg_stat_statements/expected/plancache.out | 38 +++++++++++++++++++
.../pg_stat_statements/pg_stat_statements.c | 3 +-
contrib/pg_stat_statements/sql/plancache.sql | 19 ++++++++++
3 files changed, 59 insertions(+), 1 deletion(-)
diff --git a/contrib/pg_stat_statements/expected/plancache.out b/contrib/pg_stat_statements/expected/plancache.out
index 32bf913b2861..d0796d5693c0 100644
--- a/contrib/pg_stat_statements/expected/plancache.out
+++ b/contrib/pg_stat_statements/expected/plancache.out
@@ -216,6 +216,44 @@ SELECT calls, generic_plan_calls, custom_plan_calls, toplevel, query FROM pg_sta
RESET pg_stat_statements.track;
--
+-- Procedure with internal ROLLBACK and the extended query protocol.
+-- The PlannedStmt used in pgss_ProcessUtility() is freed by the internal
+-- ROLLBACK.
+--
+CREATE OR REPLACE PROCEDURE rollback_proc(a INOUT int) AS $$
+BEGIN
+ ROLLBACK;
+END;
+$$ LANGUAGE plpgsql;
+SELECT pg_stat_statements_reset() IS NOT NULL AS t;
+ t
+---
+ t
+(1 row)
+
+CALL rollback_proc($1) \parse stmt_rollback
+\bind_named stmt_rollback 1 \g
+ a
+---
+ 1
+(1 row)
+
+\bind_named stmt_rollback 2 \g
+ a
+---
+ 2
+(1 row)
+
+SELECT calls, query FROM pg_stat_statements
+ WHERE query LIKE '%rollback_proc%'
+ ORDER BY query COLLATE "C";
+ calls | query
+-------+------------------------
+ 2 | CALL rollback_proc($1)
+(1 row)
+
+DROP PROCEDURE rollback_proc;
+--
-- Cleanup
--
DROP FUNCTION select_one_func(int);
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 95a5411a39d9..a2d3ab770cc6 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -1099,6 +1099,7 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
int64 saved_queryId = pstmt->queryId;
int saved_stmt_location = pstmt->stmt_location;
int saved_stmt_len = pstmt->stmt_len;
+ PlannedStmtOrigin saved_planOrigin = pstmt->planOrigin;
bool enabled = pgss_track_utility && pgss_enabled(nesting_level);
/*
@@ -1210,7 +1211,7 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
NULL,
0,
0,
- pstmt->planOrigin);
+ saved_planOrigin);
}
else
{
diff --git a/contrib/pg_stat_statements/sql/plancache.sql b/contrib/pg_stat_statements/sql/plancache.sql
index 160ced7add36..948d3e985180 100644
--- a/contrib/pg_stat_statements/sql/plancache.sql
+++ b/contrib/pg_stat_statements/sql/plancache.sql
@@ -87,6 +87,25 @@ SELECT calls, generic_plan_calls, custom_plan_calls, toplevel, query FROM pg_sta
RESET pg_stat_statements.track;
+--
+-- Procedure with internal ROLLBACK and the extended query protocol.
+-- The PlannedStmt used in pgss_ProcessUtility() is freed by the internal
+-- ROLLBACK.
+--
+CREATE OR REPLACE PROCEDURE rollback_proc(a INOUT int) AS $$
+BEGIN
+ ROLLBACK;
+END;
+$$ LANGUAGE plpgsql;
+SELECT pg_stat_statements_reset() IS NOT NULL AS t;
+CALL rollback_proc($1) \parse stmt_rollback
+\bind_named stmt_rollback 1 \g
+\bind_named stmt_rollback 2 \g
+SELECT calls, query FROM pg_stat_statements
+ WHERE query LIKE '%rollback_proc%'
+ ORDER BY query COLLATE "C";
+DROP PROCEDURE rollback_proc;
+
--
-- Cleanup
--
--
2.54.0