Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 16 Sep 1995 20:24:11 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        nate@rocky.sri.MT.net, piero@strider.ibenet.it
Cc:        core@Freebsd.org, security@Freebsd.org
Subject:   Re: forwarded message from Grant Haidinyak
Message-ID:  <199509161024.UAA21872@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>> [ Quick background.  Grant has been experiencing a bug whereby folks are
>> re-connected to login which were abruptly dis-connected from a machine.
>> This is a *HUGE* security hole if it is indeed true. ]
>...

>Yes it is. It was so in 2.0.0-SNAP950322, and was reported at
>least 4 months ago. It can be repeated by (on 2.0.0-SNAP):

Try this fix.  Closing the pty master cleared the tty's session pointer,
but this pointer must be kept around until the controlling terminal (the
pty slave) is last-closed.  The bug has existed for many years.

---
*** /sys/kern/tty_pty.c~	Sat Sep  9 06:44:41 1995
--- /sys/kern/tty_pty.c	Sat Sep 16 18:26:13 1995
***************
*** 323,327 ****
  
  	tp->t_oproc = 0;		/* mark closed */
- 	tp->t_session = 0;
  	return (0);
  }
--- 324,327 ----
---

There are several other bugs or at best inconsistencies in closing the
controlling terminal.

(1) if the controlling terminal is last-closed in spec_close(), then
    the process group is not sent a SIGHUP when the session leader
    exits.  This only matters in weird circumstances (perhaps never?):
    the process group must have other processes in it; these processes
    must have closed all there fd's for the controlling terminal; and
    orphanpg() must not have sent the SIGHUP for other reasons.

    Last-closing of the controlling terminal in spec_close() was
    introduced in 4.4lite.  A hack is involved.  Normally and
    previously, controlling terminals could never go away until the
    session leader exits, because the session leader holds a reference
    to the terminal so the last close() from user space was never the
    last-close.

(2) if the controlling terminal is last-closed in spec_close(), then
    the the driver waits for output to drain iff FNONBLOCK is set in the
    file flags, but if the controlling terminal is last-closed in
    exit1(), then the exit1() calls ttywait() to always wait for output
    to drain before it (indirectly) calls vclean() which calls the
    driver close with FNONBLOCK set so that the driver doesn't wait
    again (there may be more output, e.g., echos).

    I may have broken this by honoring the FNONBLOCK flag.  In
    4.4lite, vclean() passed IO_NDELAY, the driver checked IO_NDELAY,
    but spec_close() passed the file flags, where the IO_NDELAY bit
    corresponds to O_SHLOCK; thus the driver waited for output to
    drain iff O_SHLOCK was clear; I think O_SHLOCK never gets set in
    the file flags so the driver always waited for output to drain.
    Always waiting seems to be required by POSIX, although it is
    wrong.

    If waiting is required then it should be atomic with closing.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199509161024.UAA21872>