From a691a229831ad3b72d933b1858c76be44b508400 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Fri, 12 Nov 2021 21:50:08 +0900 Subject: [PATCH] Fix memory overrun when querying pg_stat_slru pg_stat_get_slru() in pgstatfuncs.c would point to one element after the end of the array PgStat_SLRUStats when finishing to scan its entries. This had no direct consequences as no data from the extra memory area was read, but static analyzers would rightfully complain here. So let's be clean. While on it, this adds one regression test in the area reserved for system views. Reported-by: Alexander Kozhemyakin, via AddressSanitizer Author: Kyotaro Horiguchi Discussion: https://postgr.es/m/17280-37da556e86032070@postgresql.org Backpatch-through: 13 --- src/backend/utils/adt/pgstatfuncs.c | 3 ++- src/test/regress/expected/sysviews.out | 7 +++++++ src/test/regress/sql/sysviews.sql | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 95738a4e34e..443dab3564a 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -1744,7 +1744,7 @@ pg_stat_get_slru(PG_FUNCTION_ARGS) /* for each row */ Datum values[PG_STAT_GET_SLRU_COLS]; bool nulls[PG_STAT_GET_SLRU_COLS]; - PgStat_SLRUStats stat = stats[i]; + PgStat_SLRUStats stat; const char *name; name = pgstat_slru_name(i); @@ -1752,6 +1752,7 @@ pg_stat_get_slru(PG_FUNCTION_ARGS) if (!name) break; + stat = stats[i]; MemSet(values, 0, sizeof(values)); MemSet(nulls, 0, sizeof(nulls)); diff --git a/src/test/regress/expected/sysviews.out b/src/test/regress/expected/sysviews.out index c3b988597c6..294c2c18faa 100644 --- a/src/test/regress/expected/sysviews.out +++ b/src/test/regress/expected/sysviews.out @@ -67,6 +67,13 @@ select count(*) >= 0 as ok from pg_prepared_xacts; t (1 row) +-- There will surely be at least one SLRU cache +select count(*) > 0 as ok from pg_stat_slru; + ok +---- + t +(1 row) + -- We expect no walreceiver running in this test select count(*) = 0 as ok from pg_stat_wal_receiver; ok diff --git a/src/test/regress/sql/sysviews.sql b/src/test/regress/sql/sysviews.sql index 5eb111d3fda..e0ddb114858 100644 --- a/src/test/regress/sql/sysviews.sql +++ b/src/test/regress/sql/sysviews.sql @@ -32,6 +32,9 @@ select count(*) = 0 as ok from pg_prepared_statements; -- See also prepared_xacts.sql select count(*) >= 0 as ok from pg_prepared_xacts; +-- There will surely be at least one SLRU cache +select count(*) > 0 as ok from pg_stat_slru; + -- We expect no walreceiver running in this test select count(*) = 0 as ok from pg_stat_wal_receiver;