diff options
author | Michael Paquier | 2025-04-07 00:51:40 +0000 |
---|---|---|
committer | Michael Paquier | 2025-04-07 00:51:40 +0000 |
commit | 3191a593d6dea56def460d06adc779f2aca44976 (patch) | |
tree | be8c7ea02583a3acd214fd8ecf0c573025d848c2 /src | |
parent | 173c97812ffcc48082355df71470974c33379d3f (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.c | 16 |
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; } |