summaryrefslogtreecommitdiff
path: root/libio
AgeCommit message (Collapse)Author
2026-03-10libio: Properly link in function _IO_wfile_doallocate in static binariesYunze Zhu
This patch addresses Bug 33935 - _IO_wfile_doallocate not linked correctly when linking glibc statically. https://sourceware.org/bugzilla/show_bug.cgi?id=33935 The function _IO_wfile_doallocate has been added with pragma weak in vtable.c, while it is the only one symbol contained in wfiledoalloc.c, and has not been directly called in libio. In static binaries the true function symbol _IO_wfile_doallocate may not be correctly linked when linking glibc with cases contains wchar functions, but the weak symbol in vtable is linked instead, and cause segmentation fault when running. This patch fixes this with similar way to symbol _IO_file_doallocate, that add libio_static_fn_required(_IO_wfile_doallocate) in wgenops.c to make _IO_wfile_doallocate always link in static binaries. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
2026-02-23libio: Fix deadlock between freopen, fflush (NULL) and fclose (bug 24963)Florian Weimer
The canonical lock ordering for stream list processing is locking list_all_lock first, then individual streams as needed. The fclose implementation reversed that, and the freopen implementation performed list operations under the reverse order, too. Unlinking in fclose was already unconditional, and the early unlinking looks unnecessary: _IO_file_close_it would call it even for !_IO_IS_FILEBUF streams. There is still a remaining concurrency defect because _IO_new_file_init_internal links in the stream before it is fully initialized, and it is not locked at this point. Reviewed-by: Arjun Shankar <arjun@redhat.com>
2026-01-01Update copyright dates with scripts/update-copyrightsPaul Eggert
2025-12-09Handle clang -Wignored-attributes on weak aliasesAdhemerval Zanella
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-05libio: null terminate the buffer upon initial allocation in getdelimCollin Funk
Commit 33eff78c8b28adc4963987880e10d96761f2a167 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-01strops: use strlen instead of strchr for string lengthKacper Piwiński
For wide string the equivalent funtion __wcslen is used. This change makes it more symetrical. Reviewed-by: Florian Weimer <fweimer@redhat.com>
2025-11-27Define C23 header version macrosJoseph Myers
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-21Enable --enable-fortify-source with clangAdhemerval Zanella
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-10-09libio: Add terminating NUL when the first character is EOF in getdelim [BZ ↵Collin Funk
#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-09-05libio: Define AT_RENAME_* with the same tokens as LinuxFlorian Weimer
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-05testsuite: Update tests for 'xfclose' useMaciej W. Rozycki
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-05testsuite: Update tests for 'xfmemopen' useMaciej W. Rozycki
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-08-22libio: Properly link in libio functions in static binariesH.J. Lu
commit 3020f72618e4f1d7338cd42b8bc7b2813e961b5a 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-06-17io: replace local_isatty() with a proper function __isatty_nostatus()H. Peter Anvin (Intel)
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-04-22Add AT_* constants from Linux 6.12Joseph Myers
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-14libio: Add test case for fflushFrédéric Bérat
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-14libio: Synthesize ESPIPE error if lseek returns 0 after reading bytesFlorian Weimer
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 be6818be31e756398e45f70e2819d78be0961223 ("Make fclose seek input file to right offset (bug 12724)"). Reviewed-by: Frédéric Bérat <fberat@redhat.com>
2025-03-03libio: Clean up fputc/putc commentsSamuel Zeter
Remove duplicate comments in stdio.h Signed-off-by: Samuel Zeter <samuelzeter@gmail.com> Reviewed-by: Arjun Shankar <arjun@redhat.com>
2025-02-13libio: Initialize _total_written for all kinds of streamsTulio Magno Quites Machado Filho
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-05libio: Replace __LP64__ with __WORDSIZETulio Magno Quites Machado Filho
__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-01-28Fix fflush handling for mmap files after ungetc (bug 32535)Joseph Myers
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-28Fix fseek handling for mmap files after ungetc or fflush (bug 32529)Joseph Myers
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-28Make fflush (NULL) flush input files (bug 32369)Joseph Myers
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-28Make fclose seek input file to right offset (bug 12724)Joseph Myers
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 eb6cbd249f4465b01f428057bf6ab61f5f0c07e3. 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-28Fix fflush after ungetc on input file (bug 5994)Joseph Myers
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-28libio: Start to return errors when flushing fwrite's buffer [BZ #29459]Tulio Magno Quites Machado Filho
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-01Update copyright dates with scripts/update-copyrightsPaul Eggert
2024-12-27libio: asprintf should write NULL upon failureFlorian Weimer
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-23Check if TEST_CC supports -Wno-restrict before using itAdhemerval Zanella
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-22Suppress Clang -Wgnu-folding-constant warningsH.J. Lu
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-22Handle pragma GCC optimize for clangAdhemerval Zanella
Reviewed-by: Sam James <sam@gentoo.org>
2024-12-17ungetc: Guarantee single char pushbackSiddhesh Poyarekar
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-17libio: Fix last NULL-as-0 issue in libioP.hSiddhesh Poyarekar
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org> Reviewed-by: Maciej W. Rozycki <macro@redhat.com>
2024-12-17libio: Use NULL instead of 0 as a null pointer constantAlejandro Colomar
This was missed in a recent global change. Fixes: 53fcdf5f743a (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-11-28libio: make _IO_least_marker staticSiddhesh Poyarekar
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-25Silence most -Wzero-as-null-pointer-constant diagnosticsAlejandro Colomar
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-10-25libio: Fix crash in fputws [BZ #20632]Peter Ammon
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-25libio: Correctly link tst-popen-fork against libpthreadArjun Shankar
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-23libio: Fix a deadlock after fork in popenArjun Shankar
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-01libio: Set _vtable_offset before calling _IO_link_in [BZ #32148]H.J. Lu
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-09-20Add another test for fclose on an unopened fileAaron Merey
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-05Fix freopen handling of ,ccs= (bug 23675)Joseph Myers
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-05Test fclose on an unopened file.Aaron Merey
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-05Fix memory leak on freopen error return (bug 32140)Joseph Myers
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-05Clear flags2 flags set from mode in freopen (bug 32134)Joseph Myers
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-04libio: Attempt wide backup free only for non-legacy codeSiddhesh Poyarekar
_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-08-15ungetc: Fix backup buffer leak on program exit [BZ #27821]Siddhesh Poyarekar
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-15ungetc: Fix uninitialized read when putting into unused streams [BZ #27821]Siddhesh Poyarekar
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-14libio/tst-getdelim: Add new test covering NUL as a delimiterFrédéric Bérat
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-05Fix name space violation in fortify wrappers (bug 32052)Andreas Schwab
Rename the identifier sz to __sz everywhere. Fixes: a643f60c53 ("Make sure that the fortified function conditionals are constant")