• Jiri Slaby's avatar
    TTY: open/hangup race fixup · acfa747b
    Jiri Slaby authored
    Like in the "TTY: don't allow reopen when ldisc is changing" patch,
    this one fixes a TTY WARNING as described in the option 1) there:
    1) __tty_hangup from tty_ldisc_hangup to tty_ldisc_enable. During this
    section tty_lock is held. However tty_lock is temporarily dropped in
    the middle of the function by tty_ldisc_hangup.
    
    The fix is to introduce a new flag which we set during the unlocked
    window and check it in tty_reopen too. The flag is TTY_HUPPING and is
    cleared after TTY_HUPPED is set.
    
    While at it, remove duplicate TTY_HUPPED set_bit. The one after
    calling ops->hangup seems to be more correct. But anyway, we hold
    tty_lock, so there should be no difference.
    
    Also document the function it does that kind of crap.
    
    Nicely reproducible with two forked children:
    static void do_work(const char *tty)
    {
    	if (signal(SIGHUP, SIG_IGN) == SIG_ERR) exit(1);
    	setsid();
    	while (1) {
    		int fd = open(tty, O_RDWR|O_NOCTTY);
    		if (fd < 0) continue;
    		if (ioctl(fd, TIOCSCTTY)) continue;
    		if (vhangup()) continue;
    		close(fd);
    	}
    	exit(0);
    }
    Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
    Reported-by: <Valdis.Kletnieks@vt.edu>
    Reported-by: default avatarKyle McMartin <kyle@mcmartin.ca>
    Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
    Cc: stable <stable@kernel.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
    acfa747b
tty_io.c 80.3 KB