1017 Commits

Author SHA1 Message Date
Paul Eggert
66f3e9219d Update copyright dates with scripts/update-copyrights 2026-01-01 13:42:29 -08:00
Adhemerval Zanella
6b7067460f Handle clang -Wignored-attributes on weak aliases
Clang issues a warning for double alias redirection, indicating that thei
original symbol is used even if a weak definition attempts to override it.

For instance, in the construction:

  int __internal_impl (...) {}
  weak_alias (__internal_impl, external_impl);
  #if SOMETHING
  weak_alias (external_impl, another_external_impl)
  #endif

Clang warns that another_external_impl always resolves to __internal_impl,
even if external_impl is a weak reference. Using the internal symbol for
both aliases resolves this warning.

This issue also occurs with certain libc_hidden_def usage:

  int __internal_impl (...) {}
  weak_alias (__internal_impl, __internal_alias)
  libc_hidden_weak (__internal_alias)

In this case, using a strong_alias is sufficient to avoid the warning
(since the alias is internal, there is no need to use a weak alias).

However, for the constructions like:

  int __internal_impl (...) {}
  weak_alias (__internal_impl, __internal_alias)
  libc_hidden_def (__internal_alias)
  weak_alias (__internal_impl, external_alias)
  libc_hidden_def (external_alias)

Clang warns that the internal external_alias will always resolve to
__GI___internal_impl, even if a weak definition of __GI_internal_impl is
overridden.  For this case, a new macro named static_weak_alias is used
to create a strong alias for SHARED, or a weak_alias otherwise.

With these changes, there is no need to check and enable the
-Wno-ignored-attributes suppression when using clang.

Checked with a build on affected ABIs, and a full check on aarch64,
armhf, i686, and x86_64.

Reviewed-by: Sam James <sam@gentoo.org>
2025-12-09 08:58:10 -03:00
Collin Funk
866fa41ef8 libio: null terminate the buffer upon initial allocation in getdelim
Commit 33eff78c8b caused issues in nbdkit
which had code similar to this to get the last line of the file:

    while (getline (&line, &len, fp) != -1)
      ;
    /* Process LINE.  */

After that commit, line[0] would be equal to '\0' instead of containing
the last line of the file like before that commit. A recent POSIX issue
clarified that the behavior before and after that commit are allowed,
since the contents of LINE are unspecified after -1 is returned
[1]. However, some programs rely on the previous behavior.

This patch null terminates the buffer upon getdelim/getline's initial
allocation. This is compatible with previous glibc versions, while also
protecting the caller from reading uninitialized memory if the file is
empty, as long as getline/getdelim does the initial allocation.

[1] https://www.austingroupbugs.net/bug_view_page.php?bug_id=1953

Suggested-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2025-12-05 20:09:36 -08:00
Kacper Piwiński
82f4758410 strops: use strlen instead of strchr for string length
For wide string the equivalent funtion __wcslen is used. This change
makes it more symetrical.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
2025-12-01 16:42:54 +01:00
Joseph Myers
e535fb910c Define C23 header version macros
C23 defines library macros __STDC_VERSION_<header>_H__ to indicate
that a header has support for new / changed features from C23.  Now
that all the required library features are implemented in glibc,
define these macros.  I'm not sure this is sufficiently much of a
user-visible feature to be worth a mention in NEWS.

Tested for x86_64.

There are various optional C23 features we don't yet have, of which I
might look at the Annex H ones (floating-point encoding conversion
functions and _Float16 functions) next.

* Optional time bases TIME_MONOTONIC, TIME_ACTIVE, TIME_THREAD_ACTIVE.
  See
  <https://sourceware.org/pipermail/libc-alpha/2023-June/149264.html>
  - we need to review / update that patch.  (I think patch 2/2,
  inventing new names for all the nonstandard CLOCK_* supported by the
  Linux kernel, is rather more dubious.)

* Updating conform/ tests for C23.

* Defining the rounding mode macro FE_TONEARESTFROMZERO for RISC-V (as
  far as I know, the only architecture supported by glibc that has
  hardware support for this rounding mode for binary floating point)
  and supporting it throughout glibc and its tests (especially the
  string/numeric conversions in both directions that explicitly handle
  each possible rounding mode, and various tests that do likewise).

* Annex H floating-point encoding conversion functions.  (It's not
  entirely clear which are optional even given support for Annex H;
  there's some wording applied inconsistently about only being
  required when non-arithmetic interchange formats are supported; see
  the comments I raised on the WG14 reflector on 23 Oct 2025.)

* _Float16 functions (and other header and testcase support for this
  type).

* Decimal floating-point support.

* Fully supporting __int128 and unsigned __int128 as integer types
  wider than intmax_t, as permitted by C23.  Would need doing in
  coordination with GCC, see GCC bug 113887 for more discussion of
  what's involved.
2025-11-27 19:32:49 +00:00
Adhemerval Zanella
8d26bed1eb Enable --enable-fortify-source with clang
clang generates internal calls for some _chk symbol, so add internal
aliases for them, and stub some with rtld-stubbed-symbols to avoid
ld.so linker issues.

Reviewed-by: Sam James <sam@gentoo.org>
2025-11-21 13:13:11 -03:00
Collin Funk
33eff78c8b libio: Add terminating NUL when the first character is EOF in getdelim [BZ #28038]
POSIX requires that the buffer used by getdelim/getline add a
terminating NUL whenever an EOF is read.

* libio/iogetdelim.c (__getdelim): Add a NUL byte when the first
__underflow is called.
* libio/tst-getdelim.c (do_test): Add a test case for the bug.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
2025-10-09 17:38:01 -07:00
Florian Weimer
b173557da9 libio: Define AT_RENAME_* with the same tokens as Linux
Linux uses different expressions for the RENAME_* and AT_RENAME_*
constants.  Mirror that in <stdio.h>, so that the macro redefinitions
do not result in preprocessor warnings.

Reviewed-by: Collin Funk <collin.funk1@gmail.com>
2025-09-05 19:02:59 +02:00
Maciej W. Rozycki
5d45da09e6 testsuite: Update tests for 'xfclose' use
Convert (some) tests to use 'xfclose' rather than using plain 'fclose'
call with no error checking or plain missing such a call.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
2025-09-05 11:53:31 +01:00
Maciej W. Rozycki
2d47b01de0 testsuite: Update tests for 'xfmemopen' use
Convert tests to use 'xfmemopen' rather than open-coding error checks
with 'fmemopen' or plain missing them, where 'fmemopen' itself is not
the scope of testing.  Leave 'fmemopen' tests alone.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
2025-09-05 11:53:31 +01:00
H.J. Lu
b4ab549ae5 libio: Properly link in libio functions in static binaries
commit 3020f72618
Author: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
Date:   Tue Dec 27 18:11:43 2022 -0300

    libio: Remove the usage of __libc_IO_vtables

added

 #define libio_static_fn_required(name) __asm (".globl " #name);

to link in libio functions in static binaries.  But there is no relocation
in
	.globl	_IO_file_open

and "strip --strip-unneeded" will remove such unreferenced symbols which
breaks static binaries.  Redefine libio_static_fn_required to create a
reference to the required function with

static __typeof (name) *const name##_p __attribute__((used)) = name;

This fixes BZ #33300.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Tested-by: Xi Ruoyao <xry111@xry111.site>
2025-08-22 12:03:00 -07:00
H. Peter Anvin (Intel)
c4929eecf7 io: replace local_isatty() with a proper function __isatty_nostatus()
Replace local_isatty() inlined in libio with a proper function
__isatty_nostatus(). This allows simpler system-specific
implementations that don't need to touch errno at all.

Note: I left the prototype in include/unistd.h (the internal header
file.) It didn't much make sense to me to put it in a different header
(not-cancel.h), but perhaps someone can elucidate the need.

Add such an implementation for Linux, with a generic fallback.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2025-06-17 09:11:38 -03:00
Joseph Myers
cf9241107d Add AT_* constants from Linux 6.12
Linux 6.12 adds AT_RENAME_* aliases for RENAME_* flags for renameat2,
and also AT_HANDLE_MNT_ID_UNIQUE.  Add the first set of aliases to
stdio.h alongside the RENAME_* names, and AT_HANDLE_MNT_ID_UNIQUE to
bits/fcntl-linux.h.

Tested for x86_64.
2025-04-22 17:00:34 +00:00
Frédéric Bérat
11e188659d libio: Add test case for fflush
Since one path uses _IO_SYNC and the other _IO_OVERFLOW, the newly added
test cases verifies that `fflush (FILE)` and `fflush (NULL)` are
semantically equivalent from the FILE perspective.

Reviewed-by: Joseph Myers <josmyers@redhat.com>
2025-04-14 13:27:12 +02:00
Florian Weimer
7b47b3dd21 libio: Synthesize ESPIPE error if lseek returns 0 after reading bytes
This is required so that fclose, when trying to seek to the right
position after filling the input buffer, does not fail with EINVAL.
This fclose code path only ignores ESPIPE errors.

Reported by Petr Pisar on
<https://bugzilla.redhat.com/show_bug.cgi?id=2358265>.

Fixes commit be6818be31 ("Make fclose
seek input file to right offset (bug 12724)").

Reviewed-by: Frédéric Bérat <fberat@redhat.com>
2025-04-14 09:59:12 +02:00
Samuel Zeter
8c6fee9f7f libio: Clean up fputc/putc comments
Remove duplicate comments in stdio.h

Signed-off-by: Samuel Zeter <samuelzeter@gmail.com>
Reviewed-by: Arjun Shankar <arjun@redhat.com>
2025-03-03 16:12:03 +01:00
Tulio Magno Quites Machado Filho
88f7ef881d libio: Initialize _total_written for all kinds of streams
Move the initialization code to a general place instead of keeping it
specific to file-backed streams.

Fixes: 596a61cf6b (libio: Start to return errors when flushing fwrite's buffer [BZ #29459], 2025-01-28)
Reported-by: Florian Weimer <fweimer@redhat.com>
Reviewed-by: Arjun Shankar <arjun@redhat.com>
2025-02-13 16:34:54 -03:00
Tulio Magno Quites Machado Filho
cdb0800022 libio: Replace __LP64__ with __WORDSIZE
__LP64__ is a GCC extension and shouldn't be used in an installed
header.

Fixes: 596a61cf6b (libio: Start to return errors when flushing fwrite's buffer [BZ #29459], 2025-01-28)
Reported-by: Florian Weimer <fweimer@redhat.com>
Reviewed-by: Arjun Shankar <arjun@redhat.com>
2025-02-05 16:18:40 -03:00
Joseph Myers
3ff3b9997c Fix fflush handling for mmap files after ungetc (bug 32535)
As discussed in bug 32535, fflush fails on files opened for reading
using mmap after ungetc.  Fix the logic to handle this case and still
compute the file offset correctly.

Tested for x86_64.
2025-01-28 23:20:08 +00:00
Joseph Myers
0dcc0b2f63 Fix fseek handling for mmap files after ungetc or fflush (bug 32529)
As discussed in bug 32529, fseek fails on files opened for reading
using mmap after ungetc.  The implementation of fseek for such files
has an offset computation that's also incorrect after fflush.  A
combined fix addresses both problems (with tests for both included as
well) and it seems reasonable to consider them a single bug.

Tested for x86_64.
2025-01-28 22:35:21 +00:00
Joseph Myers
94251ae99e Make fflush (NULL) flush input files (bug 32369)
As discussed in bug 32369 and required by POSIX, the POSIX feature
fflush (NULL) should flush input files, not just output files.  The
POSIX requirement is that "fflush() shall perform this flushing action
on all streams for which the behavior is defined above", and the
definition for input files is for "a stream open for reading with an
underlying file description, if the file is not already at EOF, and
the file is one capable of seeking".

Implement this requirement in glibc.  (The underlying flushing
implementation is what deals with avoiding errors for seeking on an
unseekable file.)

Tested for x86_64.
2025-01-28 21:53:49 +00:00
Joseph Myers
be6818be31 Make fclose seek input file to right offset (bug 12724)
As discussed in bug 12724 and required by POSIX, before an input file
(based on an underlying seekable file descriptor) is closed, fclose is
sometimes required to seek that file descriptor to the correct offset,
so that any other file descriptors sharing the underlying open file
description are left at that offset (as a motivating example, a script
could call a sequence of commands each of which processes some data
from (seekable) stdin using stdio; fclose needs to do this so that
each successive command can read exactly the data not handled by
previous commands), but glibc fails to do this.

The precise POSIX wording has changed a few times; in the 2024 edition
it's "If the file is not already at EOF, and the file is one capable
of seeking, the file offset of the underlying open file description
shall be set to the file position of the stream if the stream is the
active handle to the underlying file description.".

Add appropriate logic to _IO_new_file_close_it to handle this case.  I
haven't made any attempt to test or change things in this area for the
"old" functions.

Note that there was a previous attempt to fix bug 12724, reverted in
commit eb6cbd249f.  The fix version here
addresses the original test in that bug report without breaking the
one given in a subsequent comment in that bug report (which works with
glibc before the patch, but maybe was broken by the original fix that
was reverted).

The logic here tries to take care not to seek the file, even to its
newly computed current offset, if at EOF / possibly not the active
handle; even seeking to the current offset would be problematic
because of a potential race (fclose computes the current offset,
another thread or process with the active handle does its own seek,
fclose does a seek (not permitted by POSIX in this case) that loses
the effect of the seek on the active handle in another thread or
process).  There are tests included for various cases of being or not
being the active handle, though there aren't tests for the potential
race condition.

Tested for x86_64.
2025-01-28 20:22:56 +00:00
Joseph Myers
377e9733b5 Fix fflush after ungetc on input file (bug 5994)
As discussed in bug 5994 (plus duplicates), POSIX requires fflush
after ungetc to discard pushed-back characters but preserve the file
position indicator.  For this purpose, each ungetc decrements the file
position indicator by 1; it is unspecified after ungetc at the start
of the file, and after ungetwc, so no special handling is needed for
either of those cases.

This is fixed with appropriate logic in _IO_new_file_sync.  I haven't
made any attempt to test or change things in this area for the "old"
functions; the case of files using mmap is addressed in a subsequent
patch (and there seem to be no problems in this area with files opened
with fmemopen).

Tested for x86_64.
2025-01-28 19:38:27 +00:00
Tulio Magno Quites Machado Filho
596a61cf6b libio: Start to return errors when flushing fwrite's buffer [BZ #29459]
When an error happens, fwrite is expected to return a value that is less
than nmemb.  If this error happens while flushing its internal buffer,
fwrite is in a complex scenario: all the data might have been written to
the buffer, indicating a successful copy, but the buffer is expected to
be flushed and it was not.

POSIX.1-2024 states the following about errors on fwrite:

    If an error occurs, the resulting value of the file-position indicator
    for the stream is unspecified.

    The fwrite() function shall return the number of elements successfully
    written, which may be less than nitems if a write error is encountered.

With that in mind, this commit modifies _IO_new_file_write in order to
return the total number of bytes written via the file pointer.  It also
modifies fwrite in order to use the new information and return the
correct number of bytes written even when sputn returns EOF.

Add 2 tests:

1. tst-fwrite-bz29459: This test is based on the reproducer attached to
   bug 29459.  In order to work, it requires to pipe stdout to another
   process making it hard to reuse test-driver.c.  This code is more
   specific to the issue reported.
2. tst-fwrite-pipe: Recreates the issue by creating a pipe that is shared
   with a child process.  Reuses test-driver.c.  Evaluates a more generic
   scenario.

Co-authored-by: Florian Weimer <fweimer@redhat.com>
Reviewed-by: DJ Delorie <dj@redhat.com>
2025-01-28 15:37:44 -03:00
Paul Eggert
2642002380 Update copyright dates with scripts/update-copyrights 2025-01-01 11:22:09 -08:00
Florian Weimer
cb4692ce1e libio: asprintf should write NULL upon failure
This was suggested most recently by Solar Designer, noting
that code replacing vsprintf with vasprintf in a security fix
was subtly wrong:

  Re: GStreamer Security Advisory 2024-0003: Orc compiler
  stack-based buffer overflow
  <https://www.openwall.com/lists/oss-security/2024/07/26/2>

Previous libc-alpha discussions:

  I: [PATCH] asprintf error handling fix
  <https://inbox.sourceware.org/libc-alpha/20011205185828.GA8376@ldv.office.alt-linux.org/>

  asprintf() issue
  <https://inbox.sourceware.org/libc-alpha/CANSoFxt-cdc-+C4u-rTENMtY4X9RpRSuv+axDswSPxbDgag8_Q@mail.gmail.com/>

I don't think we need a compatibility symbol for this.  As the
GStreamer example shows, this change is much more likely to fix bugs
than cause compatibility issues.

Suggested-by: Dmitry V. Levin <ldv@altlinux.org>
Suggested-by: Archie Cobbs <archie.cobbs@gmail.com>
Suggested-by: Solar Designer <solar@openwall.com>
Reviewed-by: Sam James <sam@gentoo.org>
2024-12-27 09:18:21 +01:00
Adhemerval Zanella
2271e0d2b6 Check if TEST_CC supports -Wno-restrict before using it
Check if TEST_CC supports -Wno-restrict before using it to avoid Clang
error:

error: unknown warning option '-Wno-restrict' [-Werror,-Wunknown-warning-option]

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Reviewed-by: Sam James <sam@gentoo.org>
2024-12-23 04:32:51 +08:00
H.J. Lu
daf47b66df Suppress Clang -Wgnu-folding-constant warnings
Suppress Clang -Wgnu-folding-constant warnings, like

tst-freopen.c:44:13: error: variable length array folded to constant array as an extension [-Werror,-Wgnu-folding-constant]
   44 |   char temp[strlen (test) + 1];
      |             ^~~~~~~~~~~~~~~~~

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Reviewed-by: Sam James <sam@gentoo.org>
2024-12-22 17:45:56 +08:00
Adhemerval Zanella
a69a0bb619 Handle pragma GCC optimize for clang
Reviewed-by: Sam James <sam@gentoo.org>
2024-12-22 13:07:27 +08:00
Siddhesh Poyarekar
ae5062201d ungetc: Guarantee single char pushback
The C standard requires that ungetc guarantees at least one pushback,
but the malloc call to allocate the pushback buffer could fail, thus
violating that requirement.  Fix this by adding a single byte pushback
buffer in the FILE struct that the pushback can fall back to if malloc
fails.

The side-effect is that if the initial malloc fails and the 1-byte
fallback buffer is used, future resizing (if it succeeds) will be
2-bytes, 4-bytes and so on, which is suboptimal but it's after a malloc
failure, so maybe even desirable.

A future optimization here could be to have the pushback code use the
single byte buffer first and only fall back to malloc for subsequent
calls.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Maciej W. Rozycki <macro@redhat.com>
2024-12-17 17:42:55 -05:00
Siddhesh Poyarekar
cfdd9e7aa4 libio: Fix last NULL-as-0 issue in libioP.h
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Maciej W. Rozycki <macro@redhat.com>
2024-12-17 17:42:55 -05:00
Alejandro Colomar
bd0ea9ff7e libio: Use NULL instead of 0 as a null pointer constant
This was missed in a recent global change.

Fixes: 53fcdf5f74 (2024-11-25, "Silence most -Wzero-as-null-pointer-constant diagnostics")
Reported-by: "Maciej W. Rozycki" <macro@redhat.com>
Cc: Siddhesh Poyarekar <siddhesh@sourceware.org>
Cc: Bruno Haible <bruno@clisp.org>
Cc: Martin Uecker <uecker@tugraz.at>
Cc: Xi Ruoyao <xry111@xry111.site>
Cc: Florian Weimer <fweimer@redhat.com>
Cc: Joseph Myers <josmyers@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Maciej W. Rozycki <macro@redhat.com>
2024-12-17 06:37:24 -05:00
Siddhesh Poyarekar
293369689a libio: make _IO_least_marker static
Trivial cleanup to limit _IO_least_marker so that it's clear that it is
unused outside of genops.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2024-11-28 08:27:24 -05:00
Alejandro Colomar
53fcdf5f74 Silence most -Wzero-as-null-pointer-constant diagnostics
Replace 0 by NULL and {0} by {}.

Omit a few cases that aren't so trivial to fix.

Link: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117059>
Link: <https://software.codidact.com/posts/292718/292759#answer-292759>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-25 16:45:59 -03:00
Peter Ammon
18596c5415 libio: Fix crash in fputws [BZ #20632]
This fixes a buffer overflow in wide character string output, reproducing
when output fails, such as if the output fd is closed or is redirected
to a full device.

Wide character output data attempts to maintain the invariant that
`_IO_buf_base <= _IO_write_base <= _IO_write_end <= _IO_buf_end` (that is,
that the write region is a sub-region of `_IO_buf`). Prior to this commit,
this invariant is violated by the `_IO_wfile_overflow` function as so:

1. `_IO_wsetg` is called, assigning `_IO_write_base` to `_IO_buf_base`
2. `_IO_doallocbuf` is called, which jumps to `_IO_wfile_doallocate` via
    the _IO_wfile_jumps vtable. This function then assigns the wide data
    `_IO_buf_base` and `_IO_buf_end` to a malloc'd buffer.

Thus the invariant is violated. The fix is simply to reverse the order:
malloc the `_IO_buf` first and then assign `_IO_write_base` to it.

We also take this opportunity to defensively guard the initialization of
the number of unwritten characters via pointer arithmetic. We now check
that the buffer end is not before the buffer beginning; this matches a
similar defensive check in the narrow analogue `fileops.c`.

Add a test which fails without the fix.

Signed-off-by: Peter Ammon <corydoras@ridiculousfish.com>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2024-10-25 15:05:06 -03:00
Arjun Shankar
6a290b2895 libio: Correctly link tst-popen-fork against libpthread
tst-popen-fork failed to build for Hurd due to not being linked with
libpthread.  This commit fixes that.

Tested with build-many-glibcs.py for i686-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
2024-10-25 13:43:46 +02:00
Arjun Shankar
9f0d2c0ee6 libio: Fix a deadlock after fork in popen
popen modifies its file handler book-keeping under a lock that wasn't
being taken during fork.  This meant that a concurrent popen and fork
could end up copying the lock in a "locked" state into the fork child,
where subsequently calling popen would lead to a deadlock due to the
already (spuriously) held lock.

This commit fixes the deadlock by appropriately taking the lock before
fork, and releasing/resetting it in the parent/child after the fork.

A new test for concurrent popen and fork is also added.  It consistently
hangs (and therefore fails via timeout) without the fix applied.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
2024-10-23 13:40:16 +02:00
H.J. Lu
9dfea3de7f libio: Set _vtable_offset before calling _IO_link_in [BZ #32148]
Since _IO_vtable_offset is used to detect the old binaries, set it
in _IO_old_file_init_internal before calling _IO_link_in which checks
_IO_vtable_offset.  Add a glibc 2.0 test with copy relocation on
_IO_stderr_@GLIBC_2.0 to verify that fopen won't cause memory corruption.
This fixes BZ #32148.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
2024-10-01 07:31:25 +08:00
Aaron Merey
35dc62de3d Add another test for fclose on an unopened file
Add new file libio/tst-fclose-unopened2.c that tests whether fclose on an
unopened file returns EOF.

This test differs from tst-fclose-unopened.c by ensuring the file's buffer
is allocated prior to double-fclose.  A comment in tst-fclose-unopened.c
now clarifies that it is testing a file with an unallocated buffer.

Calling fclose on unopened files normally causes a use-after-free bug,
however the standard streams are an exception since they are not
deallocated by fclose.

Tested for x86_64.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
2024-09-20 10:32:35 -04:00
Joseph Myers
e44ca1c085 Fix freopen handling of ,ccs= (bug 23675)
As reported in bug 23675 and shown up in the recently added tests of
different cases of freopen (relevant part of the test currently
conditioned under #if 0 to avoid a failure resulting from this bug),
freopen wrongly forces the stream to unoriented even when a mode with
,ccs= is specified, though such a mode is supposed to result in a
wide-oriented stream.  Move the clearing of _mode to before the actual
reopening occurs, so that the main fopen implementation can leave a
wide-oriented stream in the ,ccs= case.

Tested for x86_64.
2024-09-05 20:08:10 +00:00
Aaron Merey
3e4a01870e Test fclose on an unopened file.
Add new file libio/tst-fclosed-unopened.c that tests whether fclose on
an unopened file returns EOF.

Calling fclose on unopened files normally causes a use-after-free bug,
however the standard streams are an exception since they are not
deallocated by fclose.

fclose returning EOF for unopened files is not part of the external
contract but there are dependancies on this behaviour.  For example,
gnulib's close_stdout in lib/closeout.c.

Tested for x86_64.

Signed-off-by: Aaron Merey <amerey@redhat.com>
2024-09-05 09:55:27 -04:00
Joseph Myers
9c0d6f7a10 Fix memory leak on freopen error return (bug 32140)
As reported in bug 32140, freopen leaks the FILE object when it
returns NULL: there is no valid use of the FILE * pointer (including
passing to freopen again or to fclose) after such an error return, so
the underlying object should be freed.  Add code to free it.

Note 1: while I think it's clear from the relevant standards that the
object should be freed and the FILE * can't be used after the call in
this case (the stream is closed, which ends the lifetime of the FILE),
it's entirely possible that some existing code does in fact try to use
the existing FILE * in some way and could be broken by this change.
(Though the most common case for freopen may be stdin / stdout /
stderr, which _IO_deallocate_file explicitly checks for and does not
deallocate.)

Note 2: the deallocation is only done in the _IO_IS_FILEBUF case.
Other kinds of streams bypass all the freopen logic handling closing
the file, meaning a call to _IO_deallocate_file would neither be safe
(the FILE might still be linked into the list of all open FILEs) nor
sufficient (other internal memory allocations associated with the file
would not have been freed).  I think the validity of freopen for any
other kind of stream will need clarifying with the Austin Group, but
if it is valid in any such case (where "valid" means "not undefined
behavior so required to close the stream" rather than "required to
successfully associate the stream with the new file in cases where
fopen would work"), more significant changes would be needed to ensure
the stream gets fully closed.

Tested for x86_64.
2024-09-05 11:16:59 +00:00
Joseph Myers
f512634dde Clear flags2 flags set from mode in freopen (bug 32134)
As reported in bug 32134, freopen does not clear the flags set in
fp->_flags2 by the "e", "m" or "c" mode characters.  Clear these so
that they can be set or not as appropriate from the mode string passed
to freopen.  The relevant test for "e" in tst-freopen2-main.c is
enabled accordingly; "c" is expected to be covered in a separately
written test (and while tst-freopen2-main.c does include transitions
to and from "m", that's not really a semantic flag intended to result
in behaving in an observably different way).

Tested for x86_64.
2024-09-05 11:15:29 +00:00
Siddhesh Poyarekar
ae4d44b1d5 libio: Attempt wide backup free only for non-legacy code
_wide_data and _mode are not available in legacy code, so do not attempt
to free the wide backup buffer in legacy code.

Resolves: BZ #32137 and BZ #27821

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
2024-09-04 09:29:35 -04:00
Siddhesh Poyarekar
3e1d8d1d1d ungetc: Fix backup buffer leak on program exit [BZ #27821]
If a file descriptor is left unclosed and is cleaned up by _IO_cleanup
on exit, its backup buffer remains unfreed, registering as a leak in
valgrind.  This is not strictly an issue since (1) the program should
ideally be closing the stream once it's not in use and (2) the program
is about to exit anyway, so keeping the backup buffer around a wee bit
longer isn't a real problem.  Free it anyway to keep valgrind happy
when the streams in question are the standard ones, i.e. stdout, stdin
or stderr.

Also, the _IO_have_backup macro checks for _IO_save_base,
which is a roundabout way to check for a backup buffer instead of
directly looking for _IO_backup_base.  The roundabout check breaks when
the main get area has not been used and user pushes a char into the
backup buffer with ungetc.  Fix this to use the _IO_backup_base
directly.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
2024-08-15 13:56:13 -04:00
Siddhesh Poyarekar
cdf0f88f97 ungetc: Fix uninitialized read when putting into unused streams [BZ #27821]
When ungetc is called on an unused stream, the backup buffer is
allocated without the main get area being present.  This results in
every subsequent ungetc (as the stream remains in the backup area)
checking uninitialized memory in the backup buffer when trying to put a
character back into the stream.

Avoid comparing the input character with buffer contents when in backup
to avoid this uninitialized read.  The uninitialized read is harmless in
this context since the location is promptly overwritten with the input
character, thus fulfilling ungetc functionality.

Also adjust wording in the manual to drop the paragraph that says glibc
cannot do multiple ungetc back to back since with this change, ungetc
can actually do this.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
2024-08-15 13:55:07 -04:00
Frédéric Bérat
3f54e459a6 libio/tst-getdelim: Add new test covering NUL as a delimiter
Add a new test to getdelim to verify that '\0' can be set as a
delimiter.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
2024-08-14 11:48:34 +02:00
Andreas Schwab
39ca997ab3 Fix name space violation in fortify wrappers (bug 32052)
Rename the identifier sz to __sz everywhere.

Fixes: a643f60c53 ("Make sure that the fortified function conditionals are constant")
2024-08-05 16:49:58 +02:00
Andreas Schwab
2213b37b70 libio: handle opening a file when all files are closed (bug 31963)
_IO_list_all becomes NULL when all files (including standard files) are
closed.
2024-07-09 10:12:36 +02:00
Carlos O'Donell
a7fe3e805d Fix conditionals on mtrace-based tests (bug 31892)
The conditionals for several mtrace-based tests in catgets, elf, libio,
malloc, misc, nptl, posix, and stdio-common were incorrect leading to
test failures when bootstrapping glibc without perl.

The correct conditional for mtrace-based tests requires three checks:
first checking for run-built-tests, then build-shared, and lastly that
PERL is not equal to "no" (missing perl).
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2024-07-01 17:20:30 +02:00