[Bug 278556] strerror-related race condition and standards violation in printf and friends

From: <bugzilla-noreply_at_freebsd.org>
Date: Tue, 23 Apr 2024 17:00:06 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=278556

Warner Losh <imp@FreeBSD.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |imp@FreeBSD.org

--- Comment #1 from Warner Losh <imp@FreeBSD.org> ---
I came to the same suggested solution after only reading the first half of your
excellent bug report, so I agree with the suggested solution. ML_TEXTMAX is
huge, but not really anymore (2k). The following leverages off of the buffer we
already need to allocate for digit accumulation:
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
index 6c7c6982c8dc..622cb57f5e7d 100644
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -44,7 +44,7 @@
  */

 #include "namespace.h"
-#include <sys/types.h>
+#include <sys/param.h>

 #include <ctype.h>
 #include <errno.h>
@@ -354,7 +354,7 @@ __vfprintf(FILE *fp, locale_t locale, const char *fmt0,
va_list ap)
        int prsize;             /* max size of printed field */
        const char *xdigs;      /* digits for %[xX] conversion */
        struct io_state io;     /* I/O buffering state */
-   char buf[BUF];          /* buffer with space for digits of uintmax_t */
+ char buf[MAX(BUF, NL_TEXTMAX)]; /* buffer with space for digits of uintmax_t
or errno string */
        char ox[2];             /* space for 0x; ox[1] is either x, X, or \0 */
        union arg *argtable;    /* args, built due to positional arg */
        union arg statargtable [STATIC_ARG_TBL_SIZE];
@@ -829,7 +829,9 @@ reswitch:   switch (ch) {
                        break;
 #endif /* !NO_FLOATING_POINT */
                case 'm':
-                   cp = strerror(saved_errno);
+                 if (strerror_r(saved_errno, buf, sizeof(buf)) != 0)
+                         strlcpy(buf, "error not available", sizeof(buf));
+                 cp = buf;
                        size = (prec >= 0) ? strnlen(cp, prec) : strlen(cp);
                        sign = '\0';
                        break;

-- 
You are receiving this mail because:
You are the assignee for the bug.