Clear flags2 flags set from mode in freopen (bug 32134)

Message ID d4dd959-adc-bfe0-19db-56cdd0bdf772@redhat.com
State Committed
Commit f512634ddef242ef0ff025ddeba64ce51035040f
Headers
Series Clear flags2 flags set from mode in freopen (bug 32134) |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
redhat-pt-bot/TryBot-32bit success Build for i686
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Test passed

Commit Message

Joseph Myers Sept. 4, 2024, 8:46 p.m. UTC
  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.
  

Comments

Florian Weimer Sept. 5, 2024, 4:16 a.m. UTC | #1
* 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.

Looks okay.  The _flags2 field is available in the old version of the
FILE struct.

Reviewed-by: Florian Weimer <fweimer@redhat.com>

Thanks,
Florian
  

Patch

diff --git a/libio/freopen.c b/libio/freopen.c
index c7e36db775..f6c943ddf8 100644
--- a/libio/freopen.c
+++ b/libio/freopen.c
@@ -63,6 +63,9 @@  freopen (const char *filename, const char *mode, FILE *fp)
 	 up here. */
       _IO_old_file_close_it (fp);
       _IO_JUMPS_FUNC_UPDATE (fp, &_IO_old_file_jumps);
+      fp->_flags2 &= ~(_IO_FLAGS2_MMAP
+		       | _IO_FLAGS2_NOTCANCEL
+		       | _IO_FLAGS2_CLOEXEC);
       result = _IO_old_file_fopen (fp, gfilename, mode);
     }
   else
@@ -72,6 +75,9 @@  freopen (const char *filename, const char *mode, FILE *fp)
       _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
       if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL)
 	fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
+      fp->_flags2 &= ~(_IO_FLAGS2_MMAP
+		       | _IO_FLAGS2_NOTCANCEL
+		       | _IO_FLAGS2_CLOEXEC);
       result = _IO_file_fopen (fp, gfilename, mode, 1);
       if (result != NULL)
 	result = __fopen_maybe_mmap (result);
diff --git a/libio/freopen64.c b/libio/freopen64.c
index 9a6d5ed801..0f3cb16331 100644
--- a/libio/freopen64.c
+++ b/libio/freopen64.c
@@ -56,6 +56,9 @@  freopen64 (const char *filename, const char *mode, FILE *fp)
   _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
   if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL)
     fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
+  fp->_flags2 &= ~(_IO_FLAGS2_MMAP
+		   | _IO_FLAGS2_NOTCANCEL
+		   | _IO_FLAGS2_CLOEXEC);
   result = _IO_file_fopen (fp, gfilename, mode, 0);
   fp->_flags2 &= ~_IO_FLAGS2_NOCLOSE;
   if (result != NULL)
diff --git a/stdio-common/tst-freopen2-main.c b/stdio-common/tst-freopen2-main.c
index 22b21afebf..5dad41c76b 100644
--- a/stdio-common/tst-freopen2-main.c
+++ b/stdio-common/tst-freopen2-main.c
@@ -308,9 +308,7 @@  do_test (void)
   TEST_VERIFY_EXIT (fp != NULL);
   ret = fcntl (fileno (fp), F_GETFD);
   TEST_VERIFY (ret != -1);
-#if 0 /* Fails to clear FD_CLOEXEC (bug 32134).  */
   TEST_COMPARE (ret & FD_CLOEXEC, 0);
-#endif
   TEST_COMPARE_FILE_STRING (fp, "plustomore");
   xfclose (fp);
   END_TEST;