[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.