From 71edbb6f66f7139d6209334ef8734a122ba06b56 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Tue, 19 Sep 2017 14:17:20 -0700 Subject: [PATCH] Avoid use of non-portable strnlen() in pgstat_clip_activity(). The use of strnlen rather than strlen was just paranoia. Instead of giving up on the paranoia, just implement the safeguard differently. And add a comment explaining why we're careful. Author: Andres Freund Discussion: https://postgr.es/m/E1duOkJ-0001Mc-U5@gemulon.postgresql.org --- src/backend/postmaster/pgstat.c | 25 +++++++++++++++++++++---- src/include/pgstat.h | 2 +- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 1ffdac5448..9e2dce4f4c 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -6288,10 +6288,24 @@ pgstat_db_requested(Oid databaseid) * freed. */ char * -pgstat_clip_activity(const char *activity) +pgstat_clip_activity(const char *raw_activity) { - int rawlen = strnlen(activity, pgstat_track_activity_query_size - 1); - int cliplen; + char *activity; + int rawlen; + int cliplen; + + /* + * Some callers, like pgstat_get_backend_current_activity(), do not + * guarantee that the buffer isn't concurrently modified. We try to take + * care that the buffer is always terminated by a NULL byte regardless, + * but let's still be paranoid about the string's length. In those cases + * the underlying buffer is guaranteed to be + * pgstat_track_activity_query_size large. + */ + activity = pnstrdup(raw_activity, pgstat_track_activity_query_size - 1); + + /* now double-guaranteed to be NULL terminated */ + rawlen = strlen(activity); /* * All supported server-encodings make it possible to determine the length @@ -6303,5 +6317,8 @@ pgstat_clip_activity(const char *activity) */ cliplen = pg_mbcliplen(activity, rawlen, pgstat_track_activity_query_size - 1); - return pnstrdup(activity, cliplen); + + activity[cliplen] = '\0'; + + return activity; } diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 52af0aa541..089b7c3a10 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -1199,7 +1199,7 @@ extern PgStat_BackendFunctionEntry *find_funcstat_entry(Oid func_id); extern void pgstat_initstats(Relation rel); -extern char *pgstat_clip_activity(const char *activity); +extern char *pgstat_clip_activity(const char *raw_activity); /* ---------- * pgstat_report_wait_start() -