diff --git a/SOURCES/coreutils-8.30-tail-use-poll.patch b/SOURCES/coreutils-8.30-tail-use-poll.patch
new file mode 100644
index 0000000..804d567
--- /dev/null
+++ b/SOURCES/coreutils-8.30-tail-use-poll.patch
@@ -0,0 +1,469 @@
+From 95f427178720d047316e95f44777cfdf2ecf2b46 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?P=C3=A1draig=20Brady?=
+Date: Fri, 4 Jan 2019 09:29:13 -0800
+Subject: [PATCH 1/4] tail: don't exit immediately with filters on AIX
+
+* src/tail.c: Fix the check_output_available check on AIX.
+Note we don't use poll for all systems as the overhead
+of adding the gnulib poll module wouldn't be worth it
+just for this single use.
+* tests/tail-2/pipe-f.sh: Fix the test which always passed
+due to only the exit code of sleep being checked.
+* NEWS: Mention the bug fix and rearrange alphabetically.
+Fixes http://bugs.gnu.org/33946
+
+Upstream-commit: d5ab4cbe424e3e95140eec22ef828f50b2fb3067
+Signed-off-by: Kamil Dudka
+---
+ src/tail.c | 13 +++++++++++++
+ tests/tail-2/pipe-f.sh | 5 ++++-
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/src/tail.c b/src/tail.c
+index ac001d7..d63aacc 100644
+--- a/src/tail.c
++++ b/src/tail.c
+@@ -30,6 +30,9 @@
+ #include
+ #include
+ #include
++#ifdef _AIX
++# include
++#endif
+
+ #include "system.h"
+ #include "argmatch.h"
+@@ -335,6 +338,16 @@ named file in a way that accommodates renaming, removal and creation.\n\
+ static void
+ check_output_alive (void)
+ {
++#ifdef _AIX
++ /* select on AIX was seen to give a readable event immediately. */
++ struct pollfd pfd;
++ pfd.fd = STDOUT_FILENO;
++ pfd.events = POLLERR;
++
++ if (poll (&pfd, 1, 0) >= 0 && (pfd.revents & POLLERR))
++ raise (SIGPIPE);
++#endif
++
+ if (! monitor_output)
+ return;
+
+diff --git a/tests/tail-2/pipe-f.sh b/tests/tail-2/pipe-f.sh
+index 76b0d90..1126c93 100755
+--- a/tests/tail-2/pipe-f.sh
++++ b/tests/tail-2/pipe-f.sh
+@@ -37,7 +37,10 @@ compare exp out || fail=1
+
+ # This would wait indefinitely before v8.28 due to no EPIPE being
+ # generated due to no data written after the first small amount
+-timeout 10 tail -f $mode $fastpoll out | sleep .1 || fail=1
++(returns_ 124 timeout 10 tail -n2 -f $mode $fastpoll out && touch timed_out) |
++ sed 2q > out2
++test -e timed_out && fail=1
++compare exp out2 || fail=1
+
+ # This would wait indefinitely before v8.28 (until first write)
+ (returns_ 1 timeout 10 tail -f $mode $fastpoll /dev/null >&-) || fail=1
+--
+2.31.1
+
+
+From 125bb79d3e9f414533b1c29237ee3f647053d0d6 Mon Sep 17 00:00:00 2001
+From: Ayappan
+Date: Sun, 20 Jan 2019 00:17:33 -0800
+Subject: [PATCH 2/4] tail: fix recent ineffective AIX change
+
+* src/tail.c: Fix commit v8.30-40-gd5ab4cb which was ineffective.
+Fixes http://bugs.gnu.org/33946
+
+Upstream-commit: 17983b2cb3bccbb4fa69691178caddd99269bda9
+Signed-off-by: Kamil Dudka
+---
+ src/tail.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/tail.c b/src/tail.c
+index d63aacc..9ed6d48 100644
+--- a/src/tail.c
++++ b/src/tail.c
+@@ -338,6 +338,9 @@ named file in a way that accommodates renaming, removal and creation.\n\
+ static void
+ check_output_alive (void)
+ {
++ if (! monitor_output)
++ return;
++
+ #ifdef _AIX
+ /* select on AIX was seen to give a readable event immediately. */
+ struct pollfd pfd;
+@@ -346,11 +349,7 @@ check_output_alive (void)
+
+ if (poll (&pfd, 1, 0) >= 0 && (pfd.revents & POLLERR))
+ raise (SIGPIPE);
+-#endif
+-
+- if (! monitor_output)
+- return;
+-
++#else
+ struct timeval delay;
+ delay.tv_sec = delay.tv_usec = 0;
+
+@@ -362,6 +361,7 @@ check_output_alive (void)
+ and implies an error condition on output like broken pipe. */
+ if (select (STDOUT_FILENO + 1, &rfd, NULL, NULL, &delay) == 1)
+ raise (SIGPIPE);
++#endif
+ }
+
+ static bool
+--
+2.31.1
+
+
+From 7741989c3e633aa44f01d8f91332cb65a9280ba3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?P=C3=A1draig=20Brady?=
+Date: Sun, 20 Jan 2019 00:13:15 -0800
+Subject: [PATCH 3/4] tail: fix handling of broken pipes with SIGPIPE ignored
+
+* init.cfg (trap_sigpipe_or_skip_): A new function refactored from...
+* tests/misc/printf-surprise.sh: ...here.
+* tests/misc/seq-epipe.sh. Likewise.
+* src/tail.c (die_pipe): Ensure we exit upon sending SIGPIPE.
+* tests/tail-2/pipe-f.sh: Ensure we exit even if SIGPIPE is ignored.
+* NEWS: Mention the bug fix.
+
+Upstream-commit: fa50623394f491b975dbd7ad73193519dd721771
+Signed-off-by: Kamil Dudka
+---
+ init.cfg | 6 ++++++
+ src/tail.c | 14 +++++++++++---
+ tests/misc/printf-surprise.sh | 4 +---
+ tests/misc/seq-epipe.sh | 4 +---
+ tests/tail-2/pipe-f.sh | 19 ++++++++++++++-----
+ 5 files changed, 33 insertions(+), 14 deletions(-)
+
+diff --git a/init.cfg b/init.cfg
+index b6c81ab..985c8d3 100644
+--- a/init.cfg
++++ b/init.cfg
+@@ -613,6 +613,12 @@ mkfifo_or_skip_()
+ fi
+ }
+
++trap_sigpipe_or_skip_()
++{
++ (trap '' PIPE && yes | :) 2>&1 | grep -qF 'Broken pipe' ||
++ skip_ 'trapping SIGPIPE is not supported'
++}
++
+ # Disable the current test if the working directory seems to have
+ # the setgid bit set.
+ skip_if_setgid_()
+diff --git a/src/tail.c b/src/tail.c
+index 9ed6d48..16e0d73 100644
+--- a/src/tail.c
++++ b/src/tail.c
+@@ -333,6 +333,14 @@ named file in a way that accommodates renaming, removal and creation.\n\
+ exit (status);
+ }
+
++/* Ensure exit, either with SIGPIPE or EXIT_FAILURE status. */
++static void ATTRIBUTE_NORETURN
++die_pipe (void)
++{
++ raise (SIGPIPE);
++ exit (EXIT_FAILURE);
++}
++
+ /* If the output has gone away, then terminate
+ as we would if we had written to this output. */
+ static void
+@@ -348,7 +356,7 @@ check_output_alive (void)
+ pfd.events = POLLERR;
+
+ if (poll (&pfd, 1, 0) >= 0 && (pfd.revents & POLLERR))
+- raise (SIGPIPE);
++ die_pipe ();
+ #else
+ struct timeval delay;
+ delay.tv_sec = delay.tv_usec = 0;
+@@ -360,7 +368,7 @@ check_output_alive (void)
+ /* readable event on STDOUT is equivalent to POLLERR,
+ and implies an error condition on output like broken pipe. */
+ if (select (STDOUT_FILENO + 1, &rfd, NULL, NULL, &delay) == 1)
+- raise (SIGPIPE);
++ die_pipe ();
+ #endif
+ }
+
+@@ -1658,7 +1666,7 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
+ {
+ /* readable event on STDOUT is equivalent to POLLERR,
+ and implies an error on output like broken pipe. */
+- raise (SIGPIPE);
++ die_pipe ();
+ }
+ else
+ break;
+diff --git a/tests/misc/printf-surprise.sh b/tests/misc/printf-surprise.sh
+index fd88133..acac0b1 100755
+--- a/tests/misc/printf-surprise.sh
++++ b/tests/misc/printf-surprise.sh
+@@ -49,9 +49,7 @@ vm=$(get_min_ulimit_v_ env $prog %20f 0) \
+ # triggering the printf(3) misbehavior -- which, btw, is required by ISO C99.
+
+ mkfifo_or_skip_ fifo
+-
+-(trap '' PIPE && yes | :) 2>&1 | grep -qF 'Broken pipe' ||
+- skip_ 'trapping SIGPIPE is not supported'
++trap_sigpipe_or_skip_
+
+ # Disable MALLOC_PERTURB_, to avoid triggering this bug
+ # https://bugs.debian.org/481543#77
+diff --git a/tests/misc/seq-epipe.sh b/tests/misc/seq-epipe.sh
+index 3e89158..127d61c 100755
+--- a/tests/misc/seq-epipe.sh
++++ b/tests/misc/seq-epipe.sh
+@@ -18,9 +18,7 @@
+
+ . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+ print_ver_ seq
+-
+-(trap '' PIPE && yes | :) 2>&1 | grep -qF 'Broken pipe' ||
+- skip_ 'trapping SIGPIPE is not supported'
++trap_sigpipe_or_skip_
+
+ # upon EPIPE with signals ignored, 'seq' should exit with an error.
+ timeout 10 sh -c \
+diff --git a/tests/tail-2/pipe-f.sh b/tests/tail-2/pipe-f.sh
+index 1126c93..f734a61 100755
+--- a/tests/tail-2/pipe-f.sh
++++ b/tests/tail-2/pipe-f.sh
+@@ -18,6 +18,7 @@
+
+ . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+ print_ver_ tail
++trap_sigpipe_or_skip_
+
+ # Speedup the non inotify case
+ fastpoll='-s.1 --max-unchanged-stats=1'
+@@ -36,11 +37,19 @@ echo bar | returns_ 1 \
+ compare exp out || fail=1
+
+ # This would wait indefinitely before v8.28 due to no EPIPE being
+-# generated due to no data written after the first small amount
+-(returns_ 124 timeout 10 tail -n2 -f $mode $fastpoll out && touch timed_out) |
+- sed 2q > out2
+-test -e timed_out && fail=1
+-compare exp out2 || fail=1
++# generated due to no data written after the first small amount.
++# Also check tail exits if SIGPIPE is being ignored.
++# Note 'trap - SIGPIPE' is ineffective if the initiating shell
++# has ignored SIGPIPE, but that's not the normal case.
++for disposition in '' '-'; do
++ (trap "$disposition" PIPE;
++ returns_ 124 timeout 10 \
++ tail -n2 -f $mode $fastpoll out && touch timed_out) |
++ sed 2q > out2
++ test -e timed_out && fail=1
++ compare exp out2 || fail=1
++ rm -f timed_out
++done
+
+ # This would wait indefinitely before v8.28 (until first write)
+ (returns_ 1 timeout 10 tail -f $mode $fastpoll /dev/null >&-) || fail=1
+--
+2.31.1
+
+
+From 0f5760466d167e955d28a1250ffd0af347d48dc9 Mon Sep 17 00:00:00 2001
+From: Paul Eggert
+Date: Sat, 26 Jun 2021 18:23:52 -0700
+Subject: [PATCH 4/4] tail: use poll, not select
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This fixes an unlikely stack out-of-bounds write reported by
+Stepan Broz via Kamil Dudka (Bug#49209).
+* src/tail.c: Do not include .
+[!_AIX]: Include poll.h.
+(check_output_alive) [!_AIX]: Use poll instead of select.
+(tail_forever_inotify): Likewise. Simplify logic, as there is no
+need for a ‘while (len <= evbuf_off)’ loop.
+
+Upstream-commit: da0d448bca62c6305fc432f67e2c5ccc2da75346
+Signed-off-by: Kamil Dudka
+---
+ src/tail.c | 101 +++++++++++++++++++++--------------------------------
+ 1 file changed, 39 insertions(+), 62 deletions(-)
+
+diff --git a/src/tail.c b/src/tail.c
+index 16e0d73..d77c660 100644
+--- a/src/tail.c
++++ b/src/tail.c
+@@ -29,10 +29,8 @@
+ #include
+ #include
+ #include
++#include
+ #include
+-#ifdef _AIX
+-# include
+-#endif
+
+ #include "system.h"
+ #include "argmatch.h"
+@@ -55,8 +53,6 @@
+ #if HAVE_INOTIFY
+ # include "hash.h"
+ # include
+-/* 'select' is used by tail_forever_inotify. */
+-# include
+
+ /* inotify needs to know if a file is local. */
+ # include "fs.h"
+@@ -349,27 +345,12 @@ check_output_alive (void)
+ if (! monitor_output)
+ return;
+
+-#ifdef _AIX
+- /* select on AIX was seen to give a readable event immediately. */
+ struct pollfd pfd;
+ pfd.fd = STDOUT_FILENO;
+ pfd.events = POLLERR;
+
+ if (poll (&pfd, 1, 0) >= 0 && (pfd.revents & POLLERR))
+ die_pipe ();
+-#else
+- struct timeval delay;
+- delay.tv_sec = delay.tv_usec = 0;
+-
+- fd_set rfd;
+- FD_ZERO (&rfd);
+- FD_SET (STDOUT_FILENO, &rfd);
+-
+- /* readable event on STDOUT is equivalent to POLLERR,
+- and implies an error condition on output like broken pipe. */
+- if (select (STDOUT_FILENO + 1, &rfd, NULL, NULL, &delay) == 1)
+- die_pipe ();
+-#endif
+ }
+
+ static bool
+@@ -1609,7 +1590,7 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
+ /* Wait for inotify events and handle them. Events on directories
+ ensure that watched files can be re-added when following by name.
+ This loop blocks on the 'safe_read' call until a new event is notified.
+- But when --pid=P is specified, tail usually waits via the select. */
++ But when --pid=P is specified, tail usually waits via poll. */
+ while (1)
+ {
+ struct File_spec *fspec;
+@@ -1626,54 +1607,51 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
+ return false;
+ }
+
+- /* When watching a PID, ensure that a read from WD will not block
+- indefinitely. */
+- while (len <= evbuf_off)
++ if (len <= evbuf_off)
+ {
+- struct timeval delay; /* how long to wait for file changes. */
++ /* Poll for inotify events. When watching a PID, ensure
++ that a read from WD will not block indefinitely.
++ If MONITOR_OUTPUT, also poll for a broken output pipe. */
+
+- if (pid)
++ int file_change;
++ struct pollfd pfd[2];
++ do
+ {
+- if (writer_is_dead)
+- exit (EXIT_SUCCESS);
++ /* How many ms to wait for changes. -1 means wait forever. */
++ int delay = -1;
+
+- writer_is_dead = (kill (pid, 0) != 0 && errno != EPERM);
+-
+- if (writer_is_dead)
+- delay.tv_sec = delay.tv_usec = 0;
+- else
++ if (pid)
+ {
+- delay.tv_sec = (time_t) sleep_interval;
+- delay.tv_usec = 1000000 * (sleep_interval - delay.tv_sec);
++ if (writer_is_dead)
++ exit (EXIT_SUCCESS);
++
++ writer_is_dead = (kill (pid, 0) != 0 && errno != EPERM);
++
++ if (writer_is_dead || sleep_interval <= 0)
++ delay = 0;
++ else if (sleep_interval < INT_MAX / 1000 - 1)
++ {
++ /* delay = ceil (sleep_interval * 1000), sans libm. */
++ double ddelay = sleep_interval * 1000;
++ delay = ddelay;
++ delay += delay < ddelay;
++ }
+ }
++
++ pfd[0].fd = wd;
++ pfd[0].events = POLLIN;
++ pfd[1].fd = STDOUT_FILENO;
++ pfd[1].events = pfd[1].revents = 0;
++ file_change = poll (pfd, monitor_output + 1, delay);
+ }
++ while (file_change == 0);
+
+- 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"));
+- else if (FD_ISSET (STDOUT_FILENO, &rfd))
+- {
+- /* readable event on STDOUT is equivalent to POLLERR,
+- and implies an error on output like broken pipe. */
+- die_pipe ();
+- }
+- else
+- break;
+- }
++ if (file_change < 0)
++ die (EXIT_FAILURE, errno,
++ _("error waiting for inotify and output events"));
++ if (pfd[1].revents)
++ die_pipe ();
+
+- if (len <= evbuf_off)
+- {
+ len = safe_read (wd, evbuf, evlen);
+ evbuf_off = 0;
+
+@@ -2434,8 +2412,7 @@ main (int argc, char **argv)
+ if (forever && ignore_fifo_and_pipe (F, n_files))
+ {
+ /* If stdout is a fifo or pipe, then monitor it
+- so that we exit if the reader goes away.
+- Note select() on a regular file is always readable. */
++ so that we exit if the reader goes away. */
+ struct stat out_stat;
+ if (fstat (STDOUT_FILENO, &out_stat) < 0)
+ die (EXIT_FAILURE, errno, _("standard output"));
+--
+2.31.1
+
diff --git a/SOURCES/coreutils-8.32-df-duplicated-entries.patch b/SOURCES/coreutils-8.32-df-duplicated-entries.patch
new file mode 100644
index 0000000..5d39c1e
--- /dev/null
+++ b/SOURCES/coreutils-8.32-df-duplicated-entries.patch
@@ -0,0 +1,72 @@
+From 0f053de4bc3ca0cfd88a42d236881dfdddb10ee9 Mon Sep 17 00:00:00 2001
+From: Kamil Dudka
+Date: Wed, 30 Jun 2021 17:53:22 +0200
+Subject: [PATCH] df: fix duplicated remote entries due to bind mounts
+
+As originally reported in ,
+df invoked without -a printed duplicated entries for NFS mounts
+of bind mounts. This is a regression from commit v8.25-54-g1c17f61ef99,
+which introduced the use of a hash table.
+
+The proposed patch makes sure that the devlist entry seen the last time
+is used for comparison when eliminating duplicated mount entries. This
+way it worked before introducing the hash table.
+
+Patch co-authored by Roberto Bergantinos.
+
+* src/ls.c (struct devlist): Introduce the seen_last pointer.
+(devlist_for_dev): Return the devlist entry seen the last time if found.
+(filter_mount_list): Remember the devlist entry seen the last time for
+each hashed item.
+Fixes https://bugs.gnu.org/49298
+
+Upstream-commit: d6125af095c9553f38cba0696f15158f5abe4ecc
+Signed-off-by: Kamil Dudka
+---
+ src/df.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/src/df.c b/src/df.c
+index 7e01839..3e9247f 100644
+--- a/src/df.c
++++ b/src/df.c
+@@ -54,6 +54,7 @@ struct devlist
+ dev_t dev_num;
+ struct mount_entry *me;
+ struct devlist *next;
++ struct devlist *seen_last; /* valid for hashed devlist entries only */
+ };
+
+ /* Filled with device numbers of examined file systems to avoid
+@@ -689,7 +690,13 @@ devlist_for_dev (dev_t dev)
+ return NULL;
+ struct devlist dev_entry;
+ dev_entry.dev_num = dev;
+- return hash_lookup (devlist_table, &dev_entry);
++
++ struct devlist *found = hash_lookup (devlist_table, &dev_entry);
++ if (found == NULL)
++ return NULL;
++
++ /* Return the last devlist entry we have seen with this dev_num */
++ return found->seen_last;
+ }
+
+ static void
+@@ -807,8 +814,12 @@ filter_mount_list (bool devices_only)
+ devlist->dev_num = buf.st_dev;
+ devlist->next = device_list;
+ device_list = devlist;
+- if (hash_insert (devlist_table, devlist) == NULL)
++
++ struct devlist *hash_entry = hash_insert (devlist_table, devlist);
++ if (hash_entry == NULL)
+ xalloc_die ();
++ /* Ensure lookups use this latest devlist. */
++ hash_entry->seen_last = devlist;
+
+ me = me->me_next;
+ }
+--
+2.31.1
+
diff --git a/SPECS/coreutils.spec b/SPECS/coreutils.spec
index e486cf1..493fc1f 100644
--- a/SPECS/coreutils.spec
+++ b/SPECS/coreutils.spec
@@ -1,7 +1,7 @@
Summary: A set of basic GNU tools commonly used in shell scripts
Name: coreutils
Version: 8.30
-Release: 10%{?dist}
+Release: 12%{?dist}
License: GPLv3+
Group: System Environment/Base
Url: https://www.gnu.org/software/coreutils/
@@ -47,6 +47,12 @@ Patch10: coreutils-8.32-split-number.patch
# mountlist: recognize fuse.portal as dummy file system (#1952714)
Patch11: coreutils-8.32-fuse-portal.patch
+# tail: fix stack out-of-bounds write with --follow (#1974784)
+Patch12: coreutils-8.30-tail-use-poll.patch
+
+# df: fix duplicated remote entries due to bind mounts (#1962515)
+Patch17: coreutils-8.32-df-duplicated-entries.patch
+
# disable the test-lock gnulib test prone to deadlock
Patch100: coreutils-8.26-test-lock.patch
@@ -280,6 +286,12 @@ fi
%license COPYING
%changelog
+* Wed Jul 07 2021 Kamil Dudka - 8.30-12
+- df: fix duplicated remote entries due to bind mounts (#1962515)
+
+* Thu Jul 01 2021 Kamil Dudka - 8.30-11
+- tail: fix stack out-of-bounds write with --follow (#1974784)
+
* Tue Jun 08 2021 Kamil Dudka - 8.30-10
- mountlist: recognize fuse.portal as dummy file system (#1952714)