Commit 0af83220a4e41797edb0915b177dae84e6e6b57f

Authored by Oleg Nesterov
Committed by Greg Kroah-Hartman
1 parent de661dfb1d

exit: call disassociate_ctty() before exit_task_namespaces()

commit c39df5fa37b0623589508c95515b4aa1531c524e upstream.

Commit 8aac62706ada ("move exit_task_namespaces() outside of
exit_notify()") breaks pppd and the exiting service crashes the kernel:

    BUG: unable to handle kernel NULL pointer dereference at 0000000000000028
    IP: ppp_register_channel+0x13/0x20 [ppp_generic]
    Call Trace:
      ppp_asynctty_open+0x12b/0x170 [ppp_async]
      tty_ldisc_open.isra.2+0x27/0x60
      tty_ldisc_hangup+0x1e3/0x220
      __tty_hangup+0x2c4/0x440
      disassociate_ctty+0x61/0x270
      do_exit+0x7f2/0xa50

ppp_register_channel() needs ->net_ns and current->nsproxy == NULL.

Move disassociate_ctty() before exit_task_namespaces(), it doesn't make
sense to delay it after perf_event_exit_task() or cgroup_exit().

This also allows to use task_work_add() inside the (nontrivial) code
paths in disassociate_ctty().

Investigated by Peter Hurley.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Reported-by: Sree Harsha Totakura <sreeharsha@totakura.in>
Cc: Peter Hurley <peter@hurleysoftware.com>
Cc: Sree Harsha Totakura <sreeharsha@totakura.in>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Andrey Vagin <avagin@openvz.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
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>

Showing 1 changed file with 2 additions and 4 deletions Side-by-side Diff

... ... @@ -791,6 +791,8 @@
791 791 exit_shm(tsk);
792 792 exit_files(tsk);
793 793 exit_fs(tsk);
  794 + if (group_dead)
  795 + disassociate_ctty(1);
794 796 exit_task_namespaces(tsk);
795 797 exit_task_work(tsk);
796 798 check_stack_usage();
797 799  
... ... @@ -806,13 +808,9 @@
806 808  
807 809 cgroup_exit(tsk, 1);
808 810  
809   - if (group_dead)
810   - disassociate_ctty(1);
811   -
812 811 module_put(task_thread_info(tsk)->exec_domain->module);
813 812  
814 813 proc_exit_connector(tsk);
815   -
816 814 /*
817 815 * FIXME: do that only when needed, using sched_exit tracepoint
818 816 */