Fix incorrect message-printing in win32security.c.
authorTom Lane <[email protected]>
Mon, 13 Oct 2025 21:56:45 +0000 (17:56 -0400)
committerTom Lane <[email protected]>
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 <[email protected]>
Reviewed-by: Tom Lane <[email protected]>
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 155d8519a74a6c287362965047f12c8d7e3930d3..4f99f701ea5a73802ade61c2719b84b018858da9 100644 (file)
@@ -3734,13 +3734,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);
@@ -3763,7 +3774,6 @@ write_stderr(const char *fmt,...)
        fflush(stderr);
    }
 #endif
-   va_end(ap);
 }
 
 
index 8bb55e5b3ccb6413f8798168ef7ba445076cead2..b3e95044174282c1f1af7357676151439b05dcda 100644 (file)
@@ -536,6 +536,7 @@ 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);
 
 /*
  * Write a message to STDERR using only async-signal-safe functions.  This can
index 4d9d28c0d7f28c24ff9b51bb8cdb727f01aa6539..346d86e6f88d03a3e9338cf819f903efee22d7af 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);
 }