GNU bug report logs - #49209
coreutils: stack out-of-bounds write in tail --follow

Previous Next

Package: coreutils;

Reported by: Kamil Dudka <kdudka <at> redhat.com>

Date: Thu, 24 Jun 2021 14:27:01 UTC

Severity: normal

Done: Paul Eggert <eggert <at> cs.ucla.edu>

Bug is archived. No further changes may be made.

Full log


Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Kamil Dudka <kdudka <at> redhat.com>
To: bug-coreutils <at> gnu.org
Cc: sbroz <at> redhat.com
Subject: coreutils: stack out-of-bounds write in tail --follow
Date: Thu, 24 Jun 2021 16:26:33 +0200
Hello,

As originally reported by Stepan Broz (CC'd), tail --follow crashes when it
is given too many files to follow, and ulimit -n is set to >1024.

FD_SET(wd, &rfd) in tail_forever_inotify() writes beyond the stack-allocated 
variable in case wd >= FD_SETSIZE.  Minimal example:

# mkdir dir
# cd dir
# touch {1..1021}
# ulimit -n 1025
# tail -f *

The out-of-bound write could be fixed like this:

--- a/src/tail.c
+++ b/src/tail.c
@@ -1647,28 +1647,32 @@ tail_forever_inotify (int wd, struct File_spec *f, 
size_t n_files,
               if (writer_is_dead)
                 exit (EXIT_SUCCESS);

               writer_is_dead = (kill (pid, 0) != 0 && errno != EPERM);

               if (writer_is_dead)
                 delay.tv_sec = delay.tv_usec = 0;
               else
                 {
                   delay.tv_sec = (time_t) sleep_interval;
                   delay.tv_usec = 1000000 * (sleep_interval - delay.tv_sec);
                 }
             }

+           if (FD_SETSIZE <= wd)
+             die (EXIT_FAILURE, 0,
+                  _("too many open files to wait for inotify events"));
+
            fd_set rfd;
            FD_ZERO (&rfd);
            FD_SET (wd, &rfd);
            if (monitor_output)
              FD_SET (STDOUT_FILENO, &rfd);

            int file_change = select (MAX (wd, STDOUT_FILENO) + 1,
                                      &rfd, NULL, NULL, pid ? &delay: NULL);

            if (file_change == 0)
              continue;
            else if (file_change == -1)
              die (EXIT_FAILURE, errno,
                   _("error waiting for inotify and output events"));


Alternatively, we might rewrite the code to use poll() rather than select().

Kamil






This bug report was last modified 4 years and 20 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.