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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.