From: Heikki Linnakangas Date: Fri, 27 Mar 2026 10:20:38 +0000 (+0200) Subject: Avoid memory leak on error while parsing pg_stat_statements dump file X-Git-Tag: REL_18_4~99 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=25b02320e13305a03fbcbbb0202053dbcb7540d1;p=thirdparty%2Fpostgresql.git Avoid memory leak on error while parsing pg_stat_statements dump file By using palloc() instead of raw malloc(). Reported-by: Gaurav Singh Reviewed-by: Lukas Fittl Reviewed-by: Daniel Gustafsson Discussion: https://www.postgresql.org/message-id/CAEcQ1bYR9s4eQLFDjzzJHU8fj-MTbmRpW-9J-r2gsCn+HEsynw@mail.gmail.com Backpatch-through: 14 --- diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 9b3a33118f4..1c07acf231e 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -798,7 +798,7 @@ pgss_shmem_shutdown(int code, Datum arg) if (fwrite(&pgss->stats, sizeof(pgssGlobalStats), 1, file) != 1) goto error; - free(qbuffer); + pfree(qbuffer); qbuffer = NULL; if (FreeFile(file)) @@ -822,7 +822,8 @@ error: (errcode_for_file_access(), errmsg("could not write file \"%s\": %m", PGSS_DUMP_FILE ".tmp"))); - free(qbuffer); + if (qbuffer) + pfree(qbuffer); if (file) FreeFile(file); unlink(PGSS_DUMP_FILE ".tmp"); @@ -1791,7 +1792,8 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo, pgss->extent != extent || pgss->gc_count != gc_count) { - free(qbuffer); + if (qbuffer) + pfree(qbuffer); qbuffer = qtext_load_file(&qbuffer_size); } } @@ -2006,7 +2008,8 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo, LWLockRelease(pgss->lock); - free(qbuffer); + if (qbuffer) + pfree(qbuffer); } /* Number of output arguments (columns) for pg_stat_statements_info */ @@ -2293,7 +2296,7 @@ error: } /* - * Read the external query text file into a malloc'd buffer. + * Read the external query text file into a palloc'd buffer. * * Returns NULL (without throwing an error) if unable to read, eg * file not there or insufficient memory. @@ -2335,7 +2338,7 @@ qtext_load_file(Size *buffer_size) /* Allocate buffer; beware that off_t might be wider than size_t */ if (stat.st_size <= MaxAllocHugeSize) - buf = (char *) malloc(stat.st_size); + buf = (char *) palloc_extended(stat.st_size, MCXT_ALLOC_HUGE | MCXT_ALLOC_NO_OOM); else buf = NULL; if (buf == NULL) @@ -2374,7 +2377,7 @@ qtext_load_file(Size *buffer_size) (errcode_for_file_access(), errmsg("could not read file \"%s\": %m", PGSS_TEXT_FILE))); - free(buf); + pfree(buf); CloseTransientFile(fd); return NULL; } @@ -2585,7 +2588,7 @@ gc_qtexts(void) else pgss->mean_query_len = ASSUMED_LENGTH_INIT; - free(qbuffer); + pfree(qbuffer); /* * OK, count a garbage collection cycle. (Note: even though we have @@ -2602,7 +2605,8 @@ gc_fail: /* clean up resources */ if (qfile) FreeFile(qfile); - free(qbuffer); + if (qbuffer) + pfree(qbuffer); /* * Since the contents of the external file are now uncertain, mark all