summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Paquier2025-04-07 00:51:40 +0000
committerMichael Paquier2025-04-07 00:51:40 +0000
commit3191a593d6dea56def460d06adc779f2aca44976 (patch)
treebe8c7ea02583a3acd214fd8ecf0c573025d848c2 /src
parent173c97812ffcc48082355df71470974c33379d3f (diff)
Fix use-after-free in pgstat_fetch_stat_backend_by_pid()
stats_fetch_consistency set to "snapshot" causes the backend entry "beentry" retrieved by pgstat_get_beentry_by_proc_number() to be reset at the beginning of pgstat_fetch_stat_backend() when fetching the backend pgstats entry. As coded, "beentry" was being accessed after being freed. This commit moves all the accesses to "beentry" to happen before calling pgstat_fetch_stat_backend(), fixing the problem. This problem could be reached by calling the SQL functions pg_stat_get_backend_io() or pg_stat_get_backend_wal(). Issue caught by valgrind. Reported-by: Alexander Lakhin <[email protected]> Author: Bertrand Drouvot <[email protected]> Discussion: https://postgr.es/m/[email protected]
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/activity/pgstat_backend.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 187c5c76e1e..f6aaf589866 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -133,10 +133,6 @@ pgstat_fetch_stat_backend_by_pid(int pid, BackendType *bktype)
if (!pgstat_tracks_backend_bktype(beentry->st_backendType))
return NULL;
- backend_stats = pgstat_fetch_stat_backend(procNumber);
- if (!backend_stats)
- return NULL;
-
/* if PID does not match, leave */
if (beentry->st_procpid != pid)
return NULL;
@@ -144,6 +140,18 @@ pgstat_fetch_stat_backend_by_pid(int pid, BackendType *bktype)
if (bktype)
*bktype = beentry->st_backendType;
+ /*
+ * Retrieve the entry. Note that "beentry" may be freed depending on the
+ * value of stats_fetch_consistency, so do not access it from this point.
+ */
+ backend_stats = pgstat_fetch_stat_backend(procNumber);
+ if (!backend_stats)
+ {
+ if (bktype)
+ *bktype = B_INVALID;
+ return NULL;
+ }
+
return backend_stats;
}