diff options
| author | dragonpt <cesar.maximo@gmail.com> | 2015-12-27 19:15:52 +0000 |
|---|---|---|
| committer | Moyster <oysterized@gmail.com> | 2016-11-11 02:40:12 +0100 |
| commit | 63d84f67a7c04fab23a82d1e99d38e3bb4e5eab3 (patch) | |
| tree | 49cece08354c8732b60027732c4ac4fca190569e | |
| parent | d9201e2e30f4f84f98d1d8185e65442272e5fa89 (diff) | |
tty: Properly fix memleak of alloc_pid
Cylen Yao <cylen.yao@mediatek.com>
bug: 7845126 MT67x2
Memleak is due to unreleased pid->count, which execute in function:
get_pid()(pid->count++) and put_pid()(pid->count--).
The race condition as following:
task[dumpsys] task[adbd]
in disassociate_ctty() in tty_signal_session_leader()
----------------------- -------------------------
tty = get_current_tty();
// tty is not NULL
...
spin_lock_irq(¤t->sighand->siglock);
put_pid(current->signal->tty_old_pgrp);
current->signal->tty_old_pgrp = NULL;
spin_unlock_irq(¤t->sighand->siglock);
spin_lock_irq(&p->sighand->siglock);
...
p->signal->tty = NULL;
...
spin_unlock_irq(&p->sighand->siglock);
tty = get_current_tty();
// tty NULL, goto else branch by accident.
if (tty) {
...
put_pid(tty_session);
put_pid(tty_pgrp);
...
} else {
print msg
}
in task[dumpsys], in disassociate_ctty(), tty is set NULL by task[adbd],
tty_signal_session_leader(), then it goto else branch and lack of
put_pid(), cause memleak.
move spin_unlock(sighand->siglock) after get_current_tty() can avoid
the race and fix the memleak.
| -rw-r--r-- | drivers/tty/tty_io.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index e7f816395..183bbe642 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -874,9 +874,8 @@ void disassociate_ctty(int on_exit) spin_lock_irq(¤t->sighand->siglock); put_pid(current->signal->tty_old_pgrp); current->signal->tty_old_pgrp = NULL; - spin_unlock_irq(¤t->sighand->siglock); - tty = get_current_tty(); + tty = tty_kref_get(current->signal->tty); if (tty) { unsigned long flags; spin_lock_irqsave(&tty->ctrl_lock, flags); @@ -893,6 +892,7 @@ void disassociate_ctty(int on_exit) #endif } + spin_unlock_irq(¤t->sighand->siglock); /* Now clear signal->tty under the lock */ read_lock(&tasklist_lock); session_clear_tty(task_session(current)); |
