[Bug 278556] strerror-related race condition and standards violation in printf and friends
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.