]> err.no Git - linux-2.6/commitdiff
[PATCH] fix disassociate_ctty vs. fork race
authorJason Baron <jbaron@redhat.com>
Fri, 9 Sep 2005 20:02:01 +0000 (13:02 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 9 Sep 2005 20:57:31 +0000 (13:57 -0700)
Race is as follows. Process A forks process B, both being part of the same
session. Then, A calls disassociate_ctty while B forks C:

A B
==== ====
fork()
  copy_signal()
dissasociate_ctty() ....
  attach_pid(p, PIDTYPE_SID, p->signal->session);

Now, C can have current->signal->tty pointing to a freed tty structure, as
it hasn't yet been added to the session group (to have its controlling tty
cleared on the diassociate_ctty() call).

This has shown up as an oops but could be even more serious.  I haven't
tried to create a test case, but a customer has verified that the patch
below resolves the issue, which was occuring quite frequently.  I'll try
and post the test case if i can.

The patch simply checks for a NULL tty *after* it has been attached to the
proper session group and clears it as necessary.  Alternatively, we could
simply do the tty assignment after the the process is added to the proper
session group.

Signed-off-by: Jason Baron <jbaron@redhat.com>
Cc: Roland McGrath <roland@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
kernel/fork.c

index dfeadf466f185b9eb1192a94044d710adaa991e0..b25802065031e7612a5733838459d41008bd31f6 100644 (file)
@@ -1116,6 +1116,9 @@ static task_t *copy_process(unsigned long clone_flags,
                        __get_cpu_var(process_counts)++;
        }
 
+       if (!current->signal->tty && p->signal->tty)
+               p->signal->tty = NULL;
+
        nr_threads++;
        total_forks++;
        write_unlock_irq(&tasklist_lock);