Re: [PATCH] coreutils/printf: fix errno clobbering with glibc 2.43
Rasmus Villemoes via busybox <[email protected]>
| Newsgroups | gmane.linux.busybox |
|---|---|
| Message-ID | <[email protected]> |
On Tue, Mar 17 2026, Harald van Dijk via busybox <[email protected]> wrote: > On 16/03/2026 14:23, David Laight via busybox wrote: >> On Mon, 16 Mar 2026 12:40:59 +0530 >> Hemanth Kumar M D via busybox <[email protected]> wrote: >> >>> busybox printf uses errno as an accumulator and returns exit code 1 >>> if errno is non-zero. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This is the bug in busybox that should be fixed. Since glibc >>> 2.43 unexpectedly sets errno during successful printf() calls, busybox >>> printf returns exit code 1 even when output is correct: >>> >>> FAIL: printf understands %s '"x' "'y" "'zTAIL" (exit 1, expected 0) >>> FAIL: printf handles positive numbers for %f (exit 1, expected 0) >>> >>> Note: the printf output itself is correct in both cases — only the >>> exit code is wrong. >>> >>> Fix by saving and restoring errno around each printf() call in >>> coreutils/printf.c, only preserving a non-zero errno if an actual >>> error occurred (ret < 0). >> That seems like the wrong fix for the problem - but your patch is >> mangled. > > It looks like the right fix to me. No. Almost every single libc function is allowed to set errno "spuriously", one simply cannot rely on errno being 0 as an indicator for a succesful call. There are a few, documented, exceptions, such as the strtol family where any return value is possible, so one has to set errno to 0 before and then (for certain return values) check it afterwards. But very few libc functions are guaranteed not to touch errno when they succeed. The value of errno in the initial thread shall be zero at program startup (the initial value of errno in other threads is an indeterminate value) and shall otherwise be defined only after a call to a function for which it is explicitly stated to be set and until it is changed by the next function call or if the application assigns it a value. The value of errno should only be examined when it is indicated to be valid by a function's return value. No function in this volume of POSIX.1-2024 shall set errno to 0. The setting of errno after a successful call to a function is unspecified unless the description of that function specifies that errno shall not be modified. And yes, as David also points out, fprintf() itself is unlikely to return an error, at least for the I/O part - of course it may return an error if the format string is somehow invalid. But it seems that ferror() is exactly what busybox wants (after calling fflush() at the end). Rasmus _______________________________________________ busybox mailing list [email protected] https://lists.busybox.net/mailman/listinfo/busybox