Fix incorrect message-printing in win32security.c.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 13 Oct 2025 21:56:45 +0000 (17:56 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 13 Oct 2025 21:56:45 +0000 (17:56 -0400)
log_error() would probably fail completely if used, and would
certainly print garbage for anything that needed to be interpolated
into the message, because it was failing to use the correct printing
subroutine for a va_list argument.

This bug likely went undetected because the error cases this code
is used for are rarely exercised - they only occur when Windows
security API calls fail catastrophically (out of memory, security
subsystem corruption, etc).

The FRONTEND variant can be fixed just by calling vfprintf()
instead of fprintf().  However, there was no va_list variant
of write_stderr(), so create one by refactoring that function.
Following the usual naming convention for such things, call
it vwrite_stderr().

Author: Bryan Green <dbryan.green@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAF+pBj8goe4fRmZ0V3Cs6eyWzYLvK+HvFLYEYWG=TzaM+tWPnw@mail.gmail.com
Backpatch-through: 13

src/backend/utils/error/elog.c
src/include/utils/elog.h
src/port/win32security.c

index 948bec886a22895484cf4e1601d20ff029a83c87..4f66acc5a6e3d2d5123ab54cffee0f1a8f9784c0 100644 (file)
@@ -3739,13 +3739,24 @@ write_stderr(const char *fmt,...)
 {
    va_list     ap;
 
+   va_start(ap, fmt);
+   vwrite_stderr(fmt, ap);
+   va_end(ap);
+}
+
+
+/*
+ * Write errors to stderr (or by equal means when stderr is
+ * not available) - va_list version
+ */
+void
+vwrite_stderr(const char *fmt, va_list ap)
+{
 #ifdef WIN32
    char        errbuf[2048];   /* Arbitrary size? */
 #endif
 
    fmt = _(fmt);
-
-   va_start(ap, fmt);
 #ifndef WIN32
    /* On Unix, we just fprintf to stderr */
    vfprintf(stderr, fmt, ap);
@@ -3768,5 +3779,4 @@ write_stderr(const char *fmt,...)
        fflush(stderr);
    }
 #endif
-   va_end(ap);
 }
index e54eca5b4891e072f3b9135d92d75c59bed584cc..18a9fed1a6ab69844baa3754e53d8e1cf7ba4c47 100644 (file)
@@ -536,5 +536,6 @@ extern void write_jsonlog(ErrorData *edata);
  * safely (memory context, GUC load etc)
  */
 extern void write_stderr(const char *fmt,...) pg_attribute_printf(1, 2);
+extern void vwrite_stderr(const char *fmt, va_list ap) pg_attribute_printf(1, 0);
 
 #endif                         /* ELOG_H */
index bca62ab2fba8d849ebd9025de434987157aa774d..bae8329f3c9f591718a126b57aeda139ad923d3a 100644 (file)
@@ -31,9 +31,9 @@ log_error(const char *fmt,...)
 
    va_start(ap, fmt);
 #ifndef FRONTEND
-   write_stderr(fmt, ap);
+   vwrite_stderr(fmt, ap);
 #else
-   fprintf(stderr, fmt, ap);
+   vfprintf(stderr, fmt, ap);
 #endif
    va_end(ap);
 }