• Y
    tty: fix pid memleak in disassociate_ctty() · a2aa6b07
    Yi Yang 提交于
    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>
    a2aa6b07
tty_jobctrl.c 14.6 KB