[PATCH] libio: Fix race in _IO_new_file_init_internal initialization order [BZ #33785]
Florian Weimer
fweimer@redhat.com
Wed Apr 29 08:29:32 GMT 2026
* Shamil Abdulaev:
> _IO_new_file_init_internal linked the new stream into _IO_list_all
> before setting fp->_fileno to -1. A concurrent thread that walks
> _IO_list_all (for example via fflush (NULL)) could observe the stream
> with an uninitialized _fileno before initialization completed.
>
> Set _fileno = -1 before _IO_link_in so the stream is fully
> initialized when it becomes visible in the global list.
>
> This is the residual concurrency defect noted at the end of commit
> b657f72fa3 ("libio: Fix deadlock between freopen, fflush (NULL) and
> fclose (bug 24963)").
>
> Add libio/tst-file-init-race exercising concurrent fopen/fclose and
> fflush (NULL) to detect regressions.
>
> Signed-off-by: Shamil Abdulaev <ashamil435@gmail.com>
> ---
> libio/Makefile | 3 ++
> libio/fileops.c | 2 +-
> libio/tst-file-init-race.c | 66 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 70 insertions(+), 1 deletion(-)
> create mode 100644 libio/tst-file-init-race.c
>
> diff --git a/libio/Makefile b/libio/Makefile
> index 93656466df..7e448295e3 100644
> --- a/libio/Makefile
> +++ b/libio/Makefile
> @@ -107,6 +107,7 @@ tests = \
> tst-fgetc-after-eof \
> tst-fgetwc \
> tst-fgetws \
> + tst-file-init-race \
> tst-fopenloc2 \
> tst-fputws \
> tst-freopen \
> @@ -160,6 +161,8 @@ tests-static += \
>
> $(objpfx)tst-popen-fork: $(shared-thread-library)
>
> +$(objpfx)tst-file-init-race: $(shared-thread-library)
> +
> tests-internal = tst-vtables tst-vtables-interposed
>
> ifeq (yes,$(build-shared))
> diff --git a/libio/fileops.c b/libio/fileops.c
> index 8067c0a9cf..9348d7c3a1 100644
> --- a/libio/fileops.c
> +++ b/libio/fileops.c
> @@ -111,8 +111,8 @@ _IO_new_file_init_internal (struct _IO_FILE_plus *fp)
> fp->file._offset = _IO_pos_BAD;
> fp->file._flags |= CLOSED_FILEBUF_FLAGS;
>
> - _IO_link_in (fp);
> fp->file._fileno = -1;
> + _IO_link_in (fp);
> }
Thanks for investigating this and fixing it.
Would you please apply the parallel change to libio/oldfileops.c? It
looks like it has the same bug.
Florian
More information about the Libc-alpha
mailing list