• Peter Hurley's avatar
    tty: Re-open /dev/tty without tty_mutex · 52494eeb
    Peter Hurley authored
    Opening /dev/tty (ie., the controlling tty for the current task)
    is always a re-open of the underlying tty. Because holding the
    tty_lock is sufficient for safely re-opening a tty, and because
    having a tty kref is sufficient for safely acquiring the tty_lock [1],
    tty_open_current_tty() does not require holding tty_mutex.
    
    Repurpose tty_open_current_tty() to perform the re-open itself and
    refactor tty_open().
    
    [1] Analysis of safely re-opening the current tty w/o tty_mutex
    
    get_current_tty() gets a tty kref from the already kref'ed tty value of
    current->signal->tty while holding the sighand lock for the current
    task. This guarantees that the tty pointer returned from
    get_current_tty() points to a tty which remains referenceable
    while holding the kref.
    
    Although release_tty() may run concurrently, and thus the driver
    reference may be removed, release_one_tty() cannot have run, and
    won't while holding the tty kref.
    
    This, in turn, guarantees the tty_lock() can safely be acquired
    (since tty->magic and tty->legacy_mutex are still a valid dereferences).
    The tty_lock() also gets a tty kref to prevent the tty_unlock() from
    dereferencing a released tty. Thus, the kref returned from
    get_current_tty() can be released.
    
    Lastly, the first operation of tty_reopen() is to check the tty count.
    If non-zero, this ensures release_tty() is not running concurrently,
    and the driver references have not been removed.
    Reviewed-by: default avatarAlan Cox <alan@linux.intel.com>
    Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    52494eeb
tty_io.c 88.4 KB