* [PATCH v2] pid_ns: Fix race between setns'ed fork() and zap_pid_ns_processes()
@ 2017-05-12 16:11 Kirill Tkhai
2017-05-12 16:17 ` Oleg Nesterov
0 siblings, 1 reply; 4+ messages in thread
From: Kirill Tkhai @ 2017-05-12 16:11 UTC (permalink / raw)
To: mhocko, avagin, peterz, oleg, linux-kernel, rppt, ebiederm, luto,
gorcunov, akpm, mingo, ktkhai, serge
Imagine we have a pid namespace and a task from its parent's pid_ns,
which made setns() to the pid namespace. The task is doing fork(),
while the pid namespace's child reaper is dying. We have the race
between them:
Task from parent pid_ns Child reaper
copy_process() ..
alloc_pid() ..
.. zap_pid_ns_processes()
.. disable_pid_allocation()
.. read_lock(&tasklist_lock)
.. iterate over pids in pid_ns
.. kill tasks linked to pids
.. read_unlock(&tasklist_lock)
write_lock_irq(&tasklist_lock); ..
attach_pid(p, PIDTYPE_PID); ..
.. ..
So, just created task p won't receive SIGKILL signal,
and the pid namespace will be in contradictory state.
Only manual kill will help there, but does the userspace
care about this? I suppose, the most users just inject
a task into a pid namespace and wait a SIGCHLD from it.
The patch fixes the problem. It simply checks for
(pid_ns->nr_hashed & PIDNS_HASH_ADDING) in copy_process().
We do it under the tasklist_lock, and can't skip
PIDNS_HASH_ADDING as noted by Oleg:
"zap_pid_ns_processes() does disable_pid_allocation()
and then takes tasklist_lock to kill the whole namespace.
Given that copy_process() checks PIDNS_HASH_ADDING
under write_lock(tasklist) they can't race;
if copy_process() takes this lock first, the new child will
be killed, otherwise copy_process() can't miss
the change in ->nr_hashed."
If allocation is disabled, we just return -ENOMEM
like it's made for such cases in alloc_pid().
v2: Do not move disable_pid_allocation(), do not
introduce a new variable in copy_process() and simplify
the patch as suggested by Oleg Nesterov.
Account the problem with double irq enabling
found by Eric W. Biederman.
Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: Ingo Molnar <mingo@kernel.org>
CC: Peter Zijlstra <peterz@infradead.org>
CC: Oleg Nesterov <oleg@redhat.com>
CC: Mike Rapoport <rppt@linux.vnet.ibm.com>
CC: Michal Hocko <mhocko@suse.com>
CC: Andy Lutomirski <luto@kernel.org>
CC: "Eric W. Biederman" <ebiederm@xmission.com>
CC: Andrei Vagin <avagin@openvz.org>
CC: Cyrill Gorcunov <gorcunov@openvz.org>
CC: Serge Hallyn <serge@hallyn.com>
---
kernel/fork.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/kernel/fork.c b/kernel/fork.c
index bfd91b180778..d2cade9b6ad8 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1845,11 +1845,13 @@ static __latent_entropy struct task_struct *copy_process(
*/
recalc_sigpending();
if (signal_pending(current)) {
- spin_unlock(¤t->sighand->siglock);
- write_unlock_irq(&tasklist_lock);
retval = -ERESTARTNOINTR;
goto bad_fork_cancel_cgroup;
}
+ if (unlikely(!(ns_of_pid(pid)->nr_hashed & PIDNS_HASH_ADDING))) {
+ retval = -ENOMEM;
+ goto bad_fork_cancel_cgroup;
+ }
if (likely(p->pid)) {
ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
@@ -1907,6 +1909,8 @@ static __latent_entropy struct task_struct *copy_process(
return p;
bad_fork_cancel_cgroup:
+ spin_unlock(¤t->sighand->siglock);
+ write_unlock_irq(&tasklist_lock);
cgroup_cancel_fork(p);
bad_fork_free_pid:
cgroup_threadgroup_change_end(current);
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v2] pid_ns: Fix race between setns'ed fork() and zap_pid_ns_processes()
2017-05-12 16:11 [PATCH v2] pid_ns: Fix race between setns'ed fork() and zap_pid_ns_processes() Kirill Tkhai
@ 2017-05-12 16:17 ` Oleg Nesterov
2017-05-12 16:34 ` Eric W. Biederman
0 siblings, 1 reply; 4+ messages in thread
From: Oleg Nesterov @ 2017-05-12 16:17 UTC (permalink / raw)
To: Kirill Tkhai
Cc: mhocko, avagin, peterz, linux-kernel, rppt, ebiederm, luto,
gorcunov, akpm, mingo, serge
On 05/12, Kirill Tkhai wrote:
>
--- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -1845,11 +1845,13 @@ static __latent_entropy struct task_struct *copy_process(
> */
> recalc_sigpending();
> if (signal_pending(current)) {
> - spin_unlock(¤t->sighand->siglock);
> - write_unlock_irq(&tasklist_lock);
> retval = -ERESTARTNOINTR;
> goto bad_fork_cancel_cgroup;
> }
> + if (unlikely(!(ns_of_pid(pid)->nr_hashed & PIDNS_HASH_ADDING))) {
> + retval = -ENOMEM;
> + goto bad_fork_cancel_cgroup;
> + }
>
> if (likely(p->pid)) {
> ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
> @@ -1907,6 +1909,8 @@ static __latent_entropy struct task_struct *copy_process(
> return p;
>
> bad_fork_cancel_cgroup:
> + spin_unlock(¤t->sighand->siglock);
> + write_unlock_irq(&tasklist_lock);
> cgroup_cancel_fork(p);
Looks good to me.
Oleg.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2] pid_ns: Fix race between setns'ed fork() and zap_pid_ns_processes()
2017-05-12 16:17 ` Oleg Nesterov
@ 2017-05-12 16:34 ` Eric W. Biederman
2017-05-12 17:05 ` Oleg Nesterov
0 siblings, 1 reply; 4+ messages in thread
From: Eric W. Biederman @ 2017-05-12 16:34 UTC (permalink / raw)
To: Oleg Nesterov
Cc: Kirill Tkhai, mhocko, avagin, peterz, linux-kernel, rppt, luto,
gorcunov, akpm, mingo, serge
Oleg Nesterov <oleg@redhat.com> writes:
> On 05/12, Kirill Tkhai wrote:
>>
> --- a/kernel/fork.c
>> +++ b/kernel/fork.c
>> @@ -1845,11 +1845,13 @@ static __latent_entropy struct task_struct *copy_process(
>> */
>> recalc_sigpending();
>> if (signal_pending(current)) {
>> - spin_unlock(¤t->sighand->siglock);
>> - write_unlock_irq(&tasklist_lock);
>> retval = -ERESTARTNOINTR;
>> goto bad_fork_cancel_cgroup;
>> }
>> + if (unlikely(!(ns_of_pid(pid)->nr_hashed & PIDNS_HASH_ADDING))) {
>> + retval = -ENOMEM;
>> + goto bad_fork_cancel_cgroup;
>> + }
>>
>> if (likely(p->pid)) {
>> ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
>> @@ -1907,6 +1909,8 @@ static __latent_entropy struct task_struct *copy_process(
>> return p;
>>
>> bad_fork_cancel_cgroup:
>> + spin_unlock(¤t->sighand->siglock);
>> + write_unlock_irq(&tasklist_lock);
>> cgroup_cancel_fork(p);
>
> Looks good to me.
Oleg can I have a review or acked by?
Then I will queue this up.
Eric
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2] pid_ns: Fix race between setns'ed fork() and zap_pid_ns_processes()
2017-05-12 16:34 ` Eric W. Biederman
@ 2017-05-12 17:05 ` Oleg Nesterov
0 siblings, 0 replies; 4+ messages in thread
From: Oleg Nesterov @ 2017-05-12 17:05 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Kirill Tkhai, mhocko, avagin, peterz, linux-kernel, rppt, luto,
gorcunov, akpm, mingo, serge
On 05/12, Eric W. Biederman wrote:
>
> Oleg Nesterov <oleg@redhat.com> writes:
>
> > Looks good to me.
>
> Oleg can I have a review or acked by?
Sure, feel free to add
Acked-by: Oleg Nesterov <oleg@redhat.com>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-05-12 17:05 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-05-12 16:11 [PATCH v2] pid_ns: Fix race between setns'ed fork() and zap_pid_ns_processes() Kirill Tkhai
2017-05-12 16:17 ` Oleg Nesterov
2017-05-12 16:34 ` Eric W. Biederman
2017-05-12 17:05 ` Oleg Nesterov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox