]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
tee: fix a crash with unwriteable files
authorPádraig Brady <P@draigBrady.com>
Tue, 7 Mar 2023 01:12:12 +0000 (01:12 +0000)
committerPádraig Brady <P@draigBrady.com>
Tue, 7 Mar 2023 01:14:00 +0000 (01:14 +0000)
This was introduced recently with commit v9.1-166-g6b12e62d9

* src/tee.c (tee_files): Check the return from fopen()
before passing to fileno() etc.
* tests/misc/tee.sh: Add a test case.

src/tee.c
tests/misc/tee.sh

index 4fc6722d4b2c0d909d7f7265fa4211e6fda10d35..8da68230a3443a541f7667a7a0f63fbb7dce569f 100644 (file)
--- a/src/tee.c
+++ b/src/tee.c
@@ -259,11 +259,11 @@ tee_files (int nfiles, char **files, bool pipe_check)
   for (i = 1; i <= nfiles; i++)
     {
       /* Do not treat "-" specially - as mandated by POSIX.  */
-      descriptors[i] = fopen (files[i], mode_string);
-      if (pipe_check)
-        out_pollable[i] = iopoll_output_ok (fileno (descriptors[i]));
+       descriptors[i] = fopen (files[i], mode_string);
       if (descriptors[i] == NULL)
         {
+          if (pipe_check)
+            out_pollable[i] = false;
           error (output_error == output_error_exit
                  || output_error == output_error_exit_nopipe,
                  errno, "%s", quotef (files[i]));
@@ -271,6 +271,8 @@ tee_files (int nfiles, char **files, bool pipe_check)
         }
       else
         {
+          if (pipe_check)
+            out_pollable[i] = iopoll_output_ok (fileno (descriptors[i]));
           setvbuf (descriptors[i], NULL, _IONBF, 0);
           n_outputs++;
         }
index 30d64a9d2f2a1475344ebb2bf25c6c2b5489f223..63e7524c02714868eb47e7726a77b80cf34de275 100755 (executable)
@@ -74,6 +74,11 @@ retry_delay_ tee_exited .1 7 | # 12.7s (Must be > following timeout)
 test $(wc -l < err) = 0 || { cat err; fail=1; }
 test -f tee.exited || fail=1
 
+# Test with unwriteable files
+touch file.ro || framework_failure_
+chmod a-w file.ro || framework_failure_
+returns_ 1 tee -p </dev/null file.ro || fail=1
+
 # Ensure tee honors --output-error modes
 mkfifo_or_skip_ fifo
 read_fifo() { timeout 10 dd count=1 if=fifo of=/dev/null status=none & }