]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 6 Jan 2018 11:09:40 +0000 (12:09 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 6 Jan 2018 11:09:40 +0000 (12:09 +0100)
added patches:
kernel-signal.c-protect-the-signal_unkillable-tasks-from-sig_kernel_only-signals.patch
kernel-signal.c-protect-the-traced-signal_unkillable-tasks-from-sigkill.patch
kernel-signal.c-remove-the-no-longer-needed-signal_unkillable-check-in-complete_signal.patch

queue-4.14/kernel-signal.c-protect-the-signal_unkillable-tasks-from-sig_kernel_only-signals.patch [new file with mode: 0644]
queue-4.14/kernel-signal.c-protect-the-traced-signal_unkillable-tasks-from-sigkill.patch [new file with mode: 0644]
queue-4.14/kernel-signal.c-remove-the-no-longer-needed-signal_unkillable-check-in-complete_signal.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/kernel-signal.c-protect-the-signal_unkillable-tasks-from-sig_kernel_only-signals.patch b/queue-4.14/kernel-signal.c-protect-the-signal_unkillable-tasks-from-sig_kernel_only-signals.patch
new file mode 100644 (file)
index 0000000..d4bd54a
--- /dev/null
@@ -0,0 +1,36 @@
+From ac25385089f673560867eb5179228a44ade0cfc1 Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+Date: Fri, 17 Nov 2017 15:30:04 -0800
+Subject: kernel/signal.c: protect the SIGNAL_UNKILLABLE tasks from !sig_kernel_only() signals
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+commit ac25385089f673560867eb5179228a44ade0cfc1 upstream.
+
+Change sig_task_ignored() to drop the SIG_DFL && !sig_kernel_only()
+signals even if force == T.  This simplifies the next change and this
+matches the same check in get_signal() which will drop these signals
+anyway.
+
+Link: http://lkml.kernel.org/r/20171103184227.GC21036@redhat.com
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Tested-by: Kyle Huey <me@kylehuey.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/signal.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/signal.c
++++ b/kernel/signal.c
+@@ -78,7 +78,7 @@ static int sig_task_ignored(struct task_
+       handler = sig_handler(t, sig);
+       if (unlikely(t->signal->flags & SIGNAL_UNKILLABLE) &&
+-                      handler == SIG_DFL && !force)
++          handler == SIG_DFL && !(force && sig_kernel_only(sig)))
+               return 1;
+       return sig_handler_ignored(handler, sig);
diff --git a/queue-4.14/kernel-signal.c-protect-the-traced-signal_unkillable-tasks-from-sigkill.patch b/queue-4.14/kernel-signal.c-protect-the-traced-signal_unkillable-tasks-from-sigkill.patch
new file mode 100644 (file)
index 0000000..f8670cc
--- /dev/null
@@ -0,0 +1,56 @@
+From 628c1bcba204052d19b686b5bac149a644cdb72e Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+Date: Fri, 17 Nov 2017 15:30:01 -0800
+Subject: kernel/signal.c: protect the traced SIGNAL_UNKILLABLE tasks from SIGKILL
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+commit 628c1bcba204052d19b686b5bac149a644cdb72e upstream.
+
+The comment in sig_ignored() says "Tracers may want to know about even
+ignored signals" but SIGKILL can not be reported to debugger and it is
+just wrong to return 0 in this case: SIGKILL should only kill the
+SIGNAL_UNKILLABLE task if it comes from the parent ns.
+
+Change sig_ignored() to ignore ->ptrace if sig == SIGKILL and rely on
+sig_task_ignored().
+
+SISGTOP coming from within the namespace is not really right too but at
+least debugger can intercept it, and we can't drop it here because this
+will break "gdb -p 1": ptrace_attach() won't work.  Perhaps we will add
+another ->ptrace check later, we will see.
+
+Link: http://lkml.kernel.org/r/20171103184206.GB21036@redhat.com
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Tested-by: Kyle Huey <me@kylehuey.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/signal.c |   12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/kernel/signal.c
++++ b/kernel/signal.c
+@@ -94,13 +94,15 @@ static int sig_ignored(struct task_struc
+       if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig))
+               return 0;
+-      if (!sig_task_ignored(t, sig, force))
+-              return 0;
+-
+       /*
+-       * Tracers may want to know about even ignored signals.
++       * Tracers may want to know about even ignored signal unless it
++       * is SIGKILL which can't be reported anyway but can be ignored
++       * by SIGNAL_UNKILLABLE task.
+        */
+-      return !t->ptrace;
++      if (t->ptrace && sig != SIGKILL)
++              return 0;
++
++      return sig_task_ignored(t, sig, force);
+ }
+ /*
diff --git a/queue-4.14/kernel-signal.c-remove-the-no-longer-needed-signal_unkillable-check-in-complete_signal.patch b/queue-4.14/kernel-signal.c-remove-the-no-longer-needed-signal_unkillable-check-in-complete_signal.patch
new file mode 100644 (file)
index 0000000..bb7f302
--- /dev/null
@@ -0,0 +1,85 @@
+From 426915796ccaf9c2bd9bb06dc5702225957bc2e5 Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+Date: Fri, 17 Nov 2017 15:30:08 -0800
+Subject: kernel/signal.c: remove the no longer needed SIGNAL_UNKILLABLE check in complete_signal()
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+commit 426915796ccaf9c2bd9bb06dc5702225957bc2e5 upstream.
+
+complete_signal() checks SIGNAL_UNKILLABLE before it starts to destroy
+the thread group, today this is wrong in many ways.
+
+If nothing else, fatal_signal_pending() should always imply that the
+whole thread group (except ->group_exit_task if it is not NULL) is
+killed, this check breaks the rule.
+
+After the previous changes we can rely on sig_task_ignored();
+sig_fatal(sig) && SIGNAL_UNKILLABLE can only be true if we actually want
+to kill this task and sig == SIGKILL OR it is traced and debugger can
+intercept the signal.
+
+This should hopefully fix the problem reported by Dmitry.  This
+test-case
+
+       static int init(void *arg)
+       {
+               for (;;)
+                       pause();
+       }
+
+       int main(void)
+       {
+               char stack[16 * 1024];
+
+               for (;;) {
+                       int pid = clone(init, stack + sizeof(stack)/2,
+                                       CLONE_NEWPID | SIGCHLD, NULL);
+                       assert(pid > 0);
+
+                       assert(ptrace(PTRACE_ATTACH, pid, 0, 0) == 0);
+                       assert(waitpid(-1, NULL, WSTOPPED) == pid);
+
+                       assert(ptrace(PTRACE_DETACH, pid, 0, SIGSTOP) == 0);
+                       assert(syscall(__NR_tkill, pid, SIGKILL) == 0);
+                       assert(pid == wait(NULL));
+               }
+       }
+
+triggers the WARN_ON_ONCE(!(task->jobctl & JOBCTL_STOP_PENDING)) in
+task_participate_group_stop().  do_signal_stop()->signal_group_exit()
+checks SIGNAL_GROUP_EXIT and return false, but task_set_jobctl_pending()
+checks fatal_signal_pending() and does not set JOBCTL_STOP_PENDING.
+
+And his should fix the minor security problem reported by Kyle,
+SECCOMP_RET_TRACE can miss fatal_signal_pending() the same way if the
+task is the root of a pid namespace.
+
+Link: http://lkml.kernel.org/r/20171103184246.GD21036@redhat.com
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Reported-by: Kyle Huey <me@kylehuey.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Tested-by: Kyle Huey <me@kylehuey.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/signal.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/kernel/signal.c
++++ b/kernel/signal.c
+@@ -931,9 +931,9 @@ static void complete_signal(int sig, str
+        * then start taking the whole group down immediately.
+        */
+       if (sig_fatal(p, sig) &&
+-          !(signal->flags & (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) &&
++          !(signal->flags & SIGNAL_GROUP_EXIT) &&
+           !sigismember(&t->real_blocked, sig) &&
+-          (sig == SIGKILL || !t->ptrace)) {
++          (sig == SIGKILL || !p->ptrace)) {
+               /*
+                * This signal will be fatal to the whole group.
+                */
index 8504ae5d45995a85866237899a94223bb245cfb7..fe6711784b1cecb9ee95e17d5ae02d1d2b8024a7 100644 (file)
@@ -21,3 +21,6 @@ sunxi-rsb-include-of-based-modalias-in-device-uevent.patch
 fscache-fix-the-default-for-fscache_maybe_release_page.patch
 x86-cpu-avoid-unnecessary-ipis-in-arch_freq_get_on_cpu.patch
 x86-cpu-always-show-current-cpu-frequency-in-proc-cpuinfo.patch
+kernel-signal.c-protect-the-traced-signal_unkillable-tasks-from-sigkill.patch
+kernel-signal.c-protect-the-signal_unkillable-tasks-from-sig_kernel_only-signals.patch
+kernel-signal.c-remove-the-no-longer-needed-signal_unkillable-check-in-complete_signal.patch