From e29ea453683c8a484cafae24e2a2fa12bf053aee Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Date: Thu, 11 Nov 2021 10:10:19 +0900
Subject: [PATCH] Fix memory overrun of pg_stat_get_slru

The function accesses one element after the end of an array, by
accessing the array using a loop variable before exiting a loop.
Avoid that access by ending the loop in a more appropriate way.

Backpatch to 13, where slru stats was introduced.
---
 src/backend/utils/adt/pgstatfuncs.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index ff5aedc99c..51fdade9ca 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1878,6 +1878,7 @@ pg_stat_get_slru(PG_FUNCTION_ARGS)
 	MemoryContext oldcontext;
 	int			i;
 	PgStat_SLRUStats *stats;
+	const char *name;
 
 	/* check to see if caller supports us returning a tuplestore */
 	if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
@@ -1906,18 +1907,12 @@ pg_stat_get_slru(PG_FUNCTION_ARGS)
 	/* request SLRU stats from the stat collector */
 	stats = pgstat_fetch_slru();
 
-	for (i = 0;; i++)
+	for (i = 0; (name = pgstat_slru_name(i)) != NULL; i++)
 	{
 		/* for each row */
 		Datum		values[PG_STAT_GET_SLRU_COLS];
 		bool		nulls[PG_STAT_GET_SLRU_COLS];
 		PgStat_SLRUStats stat = stats[i];
-		const char *name;
-
-		name = pgstat_slru_name(i);
-
-		if (!name)
-			break;
 
 		MemSet(values, 0, sizeof(values));
 		MemSet(nulls, 0, sizeof(nulls));
-- 
2.27.0

