* [PATCH 0/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal()
@ 2015-11-05 20:17 Oleg Nesterov
2015-11-05 20:17 ` [PATCH v2 1/3] signal: change sig_task_ignored(force) to take sig_kernel_only() into account Oleg Nesterov
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Oleg Nesterov @ 2015-11-05 20:17 UTC (permalink / raw)
To: Andrew Morton, Dmitry Vyukov
Cc: Roland McGrath, amanieu, pmoore, Ingo Molnar, vdavydov,
qiaowei.ren, dave, palmer, syzkaller, Kostya Serebryany,
Alexander Potapenko, Sasha Levin, linux-kernel
On 11/05, Oleg Nesterov wrote:
>
> Cough... and on the second thought this patch needs v2. Sorry Andrew, please
> drop signal-kill-the-obsolete-signal_unkillable-check-in-complete_signal.patch
> I'll send the updated version.
>
> With this patch the parent namespace can use any fatal signal (not only SIGKILL)
> to kill the init process in container. I do not think this is actually bad, but
> in any case this should not silently come as a side effect. And this is not
> consistent with SIGNAL_UNKILLABLE/sig_kernel_only() check in get_signal().
>
> Most probably I will just resend this patch as 2/2, while 1/2 will change
> sig_task_ignored() because afaics it is not actually right too (albeit not
> really buggy).
So this replaces
signal-kill-the-obsolete-signal_unkillable-check-in-complete_signal.patch
2/3 is actually the same change, just the changelog was updated.
I'll try to send the cleanups tomorrow. sig_task_ignored() doesn't
look nice, sig_handler_ignored() must die, SIGNAL_UNKILLABLE checks
in sig_task_ignored() and get_signal() should be unified.
And to remind, we need to fix more problems I found yesterday.
Oleg.
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/3] signal: change sig_task_ignored(force) to take sig_kernel_only() into account
2015-11-05 20:17 [PATCH 0/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal() Oleg Nesterov
@ 2015-11-05 20:17 ` Oleg Nesterov
2015-11-05 20:17 ` [PATCH v2 2/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal() Oleg Nesterov
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Oleg Nesterov @ 2015-11-05 20:17 UTC (permalink / raw)
To: Andrew Morton, Dmitry Vyukov
Cc: Roland McGrath, amanieu, pmoore, Ingo Molnar, vdavydov,
qiaowei.ren, dave, palmer, syzkaller, Kostya Serebryany,
Alexander Potapenko, Sasha Levin, linux-kernel
sig_task_ignored(force => true) returns false unless sig_kernel_ignore().
This makes no sense if !sig_kernel_only(), the signal will be dropped in
get_signal() anyway.
This patch simplifies the next change and allows us to do more cleanups,
in particular we can unify the SIGNAL_UNKILLABLE/sig_kernel_only() check
in sig_task_ignored() and get_signal().
The user-visible change is that, since we drop the SIG_DFL signal early,
it won't be reported to debugger. I think this is fine, but probably we
will change this later, we need to fix this logic anyway. Currently we
rely on the fact that (say) send_sigtrap() uses force_sig_info() which
clears SIGNAL_UNKILLABLE, and this is really bad.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
kernel/signal.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/kernel/signal.c b/kernel/signal.c
index d64efad..87209e5 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -72,7 +72,7 @@ static int sig_task_ignored(struct task_struct *t, int sig, bool force)
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);
--
1.5.5.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 2/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal()
2015-11-05 20:17 [PATCH 0/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal() Oleg Nesterov
2015-11-05 20:17 ` [PATCH v2 1/3] signal: change sig_task_ignored(force) to take sig_kernel_only() into account Oleg Nesterov
@ 2015-11-05 20:17 ` Oleg Nesterov
2015-11-05 20:17 ` [PATCH v2 3/3] signal: change complete_signal() to use for_each_thread() Oleg Nesterov
2015-11-05 23:33 ` [PATCH 0/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal() Andrew Morton
3 siblings, 0 replies; 7+ messages in thread
From: Oleg Nesterov @ 2015-11-05 20:17 UTC (permalink / raw)
To: Andrew Morton, Dmitry Vyukov
Cc: Roland McGrath, amanieu, pmoore, Ingo Molnar, vdavydov,
qiaowei.ren, dave, palmer, syzkaller, Kostya Serebryany,
Alexander Potapenko, Sasha Levin, linux-kernel
complete_signal() checks SIGNAL_UNKILLABLE before it starts to destroy the
thread group, today this is unnecessary and even not 100% correct.
After the previous change 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 it does not look right. 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.
This explains WARN_ON(!JOBCTL_STOP_PENDING) in task_participate_group_stop()
triggered by the test-case from Dmitry:
int main()
{
int pid = 1;
ptrace(PTRACE_ATTACH, pid, 0, 0);
ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_EXITKILL);
sleep(1);
return 0;
}
do_signal_stop()->signal_group_exit() returns false because SIGNAL_GROUP_EXIT
is not set, but task_set_jobctl_pending() checks fatal_signal_pending() and
does not set JOBCTL_STOP_PENDING.
The test-case above needs root and (correctly) crashes the kernel, but we can
trigger the same warning inside the container or using another 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));
}
}
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
kernel/signal.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/kernel/signal.c b/kernel/signal.c
index 87209e5..7e9f6fa 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -914,7 +914,7 @@ static void complete_signal(int sig, struct task_struct *p, int group)
* 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)) {
/*
--
1.5.5.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 3/3] signal: change complete_signal() to use for_each_thread()
2015-11-05 20:17 [PATCH 0/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal() Oleg Nesterov
2015-11-05 20:17 ` [PATCH v2 1/3] signal: change sig_task_ignored(force) to take sig_kernel_only() into account Oleg Nesterov
2015-11-05 20:17 ` [PATCH v2 2/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal() Oleg Nesterov
@ 2015-11-05 20:17 ` Oleg Nesterov
2015-11-05 23:33 ` [PATCH 0/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal() Andrew Morton
3 siblings, 0 replies; 7+ messages in thread
From: Oleg Nesterov @ 2015-11-05 20:17 UTC (permalink / raw)
To: Andrew Morton, Dmitry Vyukov
Cc: Roland McGrath, amanieu, pmoore, Ingo Molnar, vdavydov,
qiaowei.ren, dave, palmer, syzkaller, Kostya Serebryany,
Alexander Potapenko, Sasha Levin, linux-kernel
change complete_signal() to use for_each_thread().
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
kernel/signal.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/kernel/signal.c b/kernel/signal.c
index 7e9f6fa..8cdde5f 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -930,12 +930,11 @@ static void complete_signal(int sig, struct task_struct *p, int group)
signal->flags = SIGNAL_GROUP_EXIT;
signal->group_exit_code = sig;
signal->group_stop_count = 0;
- t = p;
- do {
+ for_each_thread(p, t) {
task_clear_jobctl_pending(t, JOBCTL_PENDING_MASK);
sigaddset(&t->pending.signal, SIGKILL);
signal_wake_up(t, 1);
- } while_each_thread(p, t);
+ }
return;
}
}
--
1.5.5.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 0/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal()
2015-11-05 20:17 [PATCH 0/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal() Oleg Nesterov
` (2 preceding siblings ...)
2015-11-05 20:17 ` [PATCH v2 3/3] signal: change complete_signal() to use for_each_thread() Oleg Nesterov
@ 2015-11-05 23:33 ` Andrew Morton
2015-11-06 14:32 ` Oleg Nesterov
3 siblings, 1 reply; 7+ messages in thread
From: Andrew Morton @ 2015-11-05 23:33 UTC (permalink / raw)
To: Oleg Nesterov
Cc: Dmitry Vyukov, Roland McGrath, amanieu, pmoore, Ingo Molnar,
vdavydov, qiaowei.ren, dave, palmer, syzkaller, Kostya Serebryany,
Alexander Potapenko, Sasha Levin, linux-kernel
On Thu, 5 Nov 2015 21:17:20 +0100 Oleg Nesterov <oleg@redhat.com> wrote:
> On 11/05, Oleg Nesterov wrote:
> >
> > Cough... and on the second thought this patch needs v2. Sorry Andrew, please
> > drop signal-kill-the-obsolete-signal_unkillable-check-in-complete_signal.patch
> > I'll send the updated version.
> >
> > With this patch the parent namespace can use any fatal signal (not only SIGKILL)
> > to kill the init process in container. I do not think this is actually bad, but
> > in any case this should not silently come as a side effect. And this is not
> > consistent with SIGNAL_UNKILLABLE/sig_kernel_only() check in get_signal().
> >
> > Most probably I will just resend this patch as 2/2, while 1/2 will change
> > sig_task_ignored() because afaics it is not actually right too (albeit not
> > really buggy).
>
> So this replaces
> signal-kill-the-obsolete-signal_unkillable-check-in-complete_signal.patch
> 2/3 is actually the same change, just the changelog was updated.
It's awfully late. Do you see any reason why we should jam this into 4.4?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal()
2015-11-05 23:33 ` [PATCH 0/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal() Andrew Morton
@ 2015-11-06 14:32 ` Oleg Nesterov
2015-11-06 19:16 ` Oleg Nesterov
0 siblings, 1 reply; 7+ messages in thread
From: Oleg Nesterov @ 2015-11-06 14:32 UTC (permalink / raw)
To: Andrew Morton
Cc: Dmitry Vyukov, Roland McGrath, amanieu, pmoore, Ingo Molnar,
vdavydov, qiaowei.ren, dave, palmer, syzkaller, Kostya Serebryany,
Alexander Potapenko, Sasha Levin, linux-kernel
On 11/05, Andrew Morton wrote:
>
> On Thu, 5 Nov 2015 21:17:20 +0100 Oleg Nesterov <oleg@redhat.com> wrote:
>
> > On 11/05, Oleg Nesterov wrote:
> > >
> > > Cough... and on the second thought this patch needs v2. Sorry Andrew, please
> > > drop signal-kill-the-obsolete-signal_unkillable-check-in-complete_signal.patch
> > > I'll send the updated version.
> > >
> > > With this patch the parent namespace can use any fatal signal (not only SIGKILL)
> > > to kill the init process in container. I do not think this is actually bad, but
> > > in any case this should not silently come as a side effect. And this is not
> > > consistent with SIGNAL_UNKILLABLE/sig_kernel_only() check in get_signal().
> > >
> > > Most probably I will just resend this patch as 2/2, while 1/2 will change
> > > sig_task_ignored() because afaics it is not actually right too (albeit not
> > > really buggy).
> >
> > So this replaces
> > signal-kill-the-obsolete-signal_unkillable-check-in-complete_signal.patch
> > 2/3 is actually the same change, just the changelog was updated.
>
> It's awfully late. Do you see any reason why we should jam this into 4.4?
No, I think this can wait till 4.5.
Oleg.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal()
2015-11-06 14:32 ` Oleg Nesterov
@ 2015-11-06 19:16 ` Oleg Nesterov
0 siblings, 0 replies; 7+ messages in thread
From: Oleg Nesterov @ 2015-11-06 19:16 UTC (permalink / raw)
To: Andrew Morton
Cc: Dmitry Vyukov, Roland McGrath, amanieu, pmoore, Ingo Molnar,
vdavydov, qiaowei.ren, dave, palmer, syzkaller, Kostya Serebryany,
Alexander Potapenko, Sasha Levin, linux-kernel
On 11/06, Oleg Nesterov wrote:
>
> On 11/05, Andrew Morton wrote:
> >
> > On Thu, 5 Nov 2015 21:17:20 +0100 Oleg Nesterov <oleg@redhat.com> wrote:
> >
> > > So this replaces
> > > signal-kill-the-obsolete-signal_unkillable-check-in-complete_signal.patch
> > > 2/3 is actually the same change, just the changelog was updated.
> >
> > It's awfully late. Do you see any reason why we should jam this into 4.4?
>
> No, I think this can wait till 4.5.
Oh. Andrew, please ignore this version too. I'll send v3.
Because when I tried to make the promised cleanups I have found yet another
ptrace/SIGKILL/SIGNAL_UNKILLABLE bug, and it seems that it needs to change
the same code paths again. I need to think.
Dmitry, do you realize how much I hate you? ;)
Oleg.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2015-11-06 18:20 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-05 20:17 [PATCH 0/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal() Oleg Nesterov
2015-11-05 20:17 ` [PATCH v2 1/3] signal: change sig_task_ignored(force) to take sig_kernel_only() into account Oleg Nesterov
2015-11-05 20:17 ` [PATCH v2 2/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal() Oleg Nesterov
2015-11-05 20:17 ` [PATCH v2 3/3] signal: change complete_signal() to use for_each_thread() Oleg Nesterov
2015-11-05 23:33 ` [PATCH 0/3] signal: kill the obsolete SIGNAL_UNKILLABLE check in complete_signal() Andrew Morton
2015-11-06 14:32 ` Oleg Nesterov
2015-11-06 19:16 ` Oleg Nesterov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).