提交 a2aa6b07 编写于 作者: Y Yi Yang

tty: fix pid memleak in disassociate_ctty()

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7PBYJ

--------------------------------

There is memleak in alloc_pid:
------------------------------
unreferenced object 0xffff88810c181940 (size 224):
  comm "sshd", pid 8191, jiffies 4294946950 (age 524.570s)
  hex dump (first 32 bytes):
    01 00 00 00 00 00 00 00 00 00 00 00 ad 4e ad de  .............N..
    ff ff ff ff 6b 6b 6b 6b ff ff ff ff ff ff ff ff  ....kkkk........
  backtrace:
    [<ffffffff814774e6>] kmem_cache_alloc+0x5c6/0x9b0
    [<ffffffff81177342>] alloc_pid+0x72/0x570
    [<ffffffff81140ac4>] copy_process+0x1374/0x2470
    [<ffffffff81141d77>] kernel_clone+0xb7/0x900
    [<ffffffff81142645>] __se_sys_clone+0x85/0xb0
    [<ffffffff8114269b>] __x64_sys_clone+0x2b/0x30
    [<ffffffff83965a72>] do_syscall_64+0x32/0x80
    [<ffffffff83a00085>] entry_SYSCALL_64_after_hwframe+0x61/0xc6

The pid memleak is triggered by the following race:
task[sshd]                      task[bash]
-----------------------		-----------------------
				do_exit();
				disassociate_ctty();
				spin_lock_irq(¤t->sighand->siglock);
				put_pid(current->signal->tty_old_pgrp);
				current->signal->tty_old_pgrp = NULL;
				tty = tty_kref_get(current->signal->tty);
				//tty is not NULL
				spin_unlock_irq(¤t->sighand->siglock);
tty_vhangup();
tty_lock(tty);
...
tty_signal_session_leader();
spin_lock_irq(&p->sighand->siglock);
...
p->signal->tty_old_pgrp = get_pid(tty->pgrp); // tty_old_pgrp reassign
spin_unlock_irq(&p->sighand->siglock);
...
tty_unlock(tty);
				if (tty) {
				    tty_lock(tty);
				    ...
				    put_pid(tty->pgrp);
				    tty->pgrp = NULL;// It's too late
				    ...
				    tty_unlock(tty);
				}

in task[bash], tty_old_pgrp is released by disassociate_ctty(), then it's
reassigned by tty_signal_session_leader() in task[sshd], cause memleak.

fix the memleak by add put_pid() in disassociate_ctty() after tty_old_pgrp
is reassigned.

Fixes: c8bcd9c5 ("tty: Fix ->session locking")
Signed-off-by: NYi Yang <yiyang13@huawei.com>
上级 d636f566
......@@ -308,6 +308,18 @@ void disassociate_ctty(int on_exit)
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
tty_unlock(tty);
tty_kref_put(tty);
/*
* Race with tty_signal_session_leader(), current->signal
* ->tty_old_pgrp may be reassigned, put_pid() again to ensure
* the pid does not leak memory.
*/
if (on_exit) {
spin_lock_irq(&current->sighand->siglock);
put_pid(current->signal->tty_old_pgrp);
current->signal->tty_old_pgrp = NULL;
spin_unlock_irq(&current->sighand->siglock);
}
}
/* Now clear signal->tty under the lock */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册