Commit 4eedca38 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] tty oops fix

From: William Lee Irwin III <wli@holomorphy.com>

Remember to invalidate the task->tty of threads, otherwise prod_pid_stat()
later stumbles over the dangling pointers and crashes.
parent 3a1bf819
...@@ -481,12 +481,15 @@ void do_tty_hangup(void *data) ...@@ -481,12 +481,15 @@ void do_tty_hangup(void *data)
if (tty->session > 0) { if (tty->session > 0) {
struct list_head *l; struct list_head *l;
for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) { for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) {
if (p->tty == tty) task_t *task = p;
p->tty = NULL; do {
if (!p->leader) if (task->tty == tty)
continue; task->tty = NULL;
send_group_sig_info(SIGHUP, SEND_SIG_PRIV, p); if (task->leader) {
send_group_sig_info(SIGCONT, SEND_SIG_PRIV, p); send_group_sig_info(SIGHUP, SEND_SIG_PRIV, task);
send_group_sig_info(SIGCONT, SEND_SIG_PRIV, task);
}
} while_each_thread(p, task);
if (tty->pgrp > 0) if (tty->pgrp > 0)
p->tty_old_pgrp = tty->pgrp; p->tty_old_pgrp = tty->pgrp;
} }
...@@ -591,8 +594,12 @@ void disassociate_ctty(int on_exit) ...@@ -591,8 +594,12 @@ void disassociate_ctty(int on_exit)
tty->pgrp = -1; tty->pgrp = -1;
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
for_each_task_pid(current->session, PIDTYPE_SID, p, l, pid) for_each_task_pid(current->session, PIDTYPE_SID, p, l, pid) {
p->tty = NULL; task_t *task = p;
do {
task->tty = NULL;
} while_each_thread(p, task);
}
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
unlock_kernel(); unlock_kernel();
} }
...@@ -1260,11 +1267,20 @@ static void release_dev(struct file * filp) ...@@ -1260,11 +1267,20 @@ static void release_dev(struct file * filp)
struct pid *pid; struct pid *pid;
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) {
p->tty = NULL; task_t *task = p;
if (o_tty) do {
for_each_task_pid(o_tty->session, PIDTYPE_SID, p,l, pid) task->tty = NULL;
p->tty = NULL; } while_each_thread(p, task);
}
if (o_tty) {
for_each_task_pid(o_tty->session, PIDTYPE_SID, p,l, pid) {
task_t *task = p;
do {
task->tty = NULL;
} while_each_thread(p, task);
}
}
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
} }
...@@ -1615,8 +1631,12 @@ static int tiocsctty(struct tty_struct *tty, int arg) ...@@ -1615,8 +1631,12 @@ static int tiocsctty(struct tty_struct *tty, int arg)
*/ */
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) {
p->tty = NULL; task_t *task = p;
do {
task->tty = NULL;
} while_each_thread(p, task);
}
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
} else } else
return -EPERM; return -EPERM;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment