--- Begin Message ---
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
--- End Message ---
--- Begin Message ---
Subject: |
Re: bug#49209: coreutils: stack out-of-bounds write in tail --follow |
Date: |
Sat, 26 Jun 2021 18:47:46 -0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 |
On 6/24/21 8:50 AM, Paul Eggert wrote:
inotify_init can return 1025 even if called first thing, so we also need
to dup2 the result of early inotify_init down to 3 (or whatever), or at
least to check that it's less than 1024. Choosing 3 is a tricky
business, since it's not clear what fds the C library actually needs.
When looking into this I decided it was cleaner to fix coreutils by
using 'poll' instead of 'select', as Kamil suggested. I installed the
attached patches to do that. The last patch fixes the bug.
Thanks for reporting the problem.
0001-maint-while-1-while-true.patch
Description: Text Data
0002-tail-fix-abuse2-test-race.patch
Description: Text Data
0003-tail-use-poll-not-select.patch
Description: Text Data
--- End Message ---