[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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

From: Pádraig Brady
Subject: bug#49209: coreutils: stack out-of-bounds write in tail --follow
Date: Thu, 24 Jun 2021 15:50:25 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Thunderbird/84.0

On 24/06/2021 15:26, Kamil Dudka wrote:

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;
                    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)
             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().

Note the number of descriptors select() is waiting on in independent of the 
number of files.
We should be able to inotify_init() earlier in the process to avoid this issue.
I'll have a look.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]