Hello hackers,

yesterday, while playing with ptys on 5.3 kernel, I was hit by bug #83375. I have reproduced it quite easely:

% /usr/libexec/getty Pc ttyp2 &

% /usr/libexec/getty Pc ttyp2

--- kernel panic ----

ttyp2 - not used slave pty

I was curious and did some investigation why it happens. As result, I have found the source of bug. Please, look at this:

What does getty(8) do with specified device? It basically does the following steps:

- chmod(name)
- chmod(name)
- revoke(name)
- open(name)

First invocation of getty(8) does not revoke anything, and just goes to sleep in ptsopen().

Second invocation of getty(8) also does revoke(2) first. But in this case, revoke syscall calls ptsclose() routine. So we have the following call chain:

ptsclose()->tty_close()->ttyrel().

tty ref for ttyp2 is still equal to 1, since the first invocation of getty(8) sleeps awaiting for a master, and tty_open is not called yet.
Hence, ttyrel() above simply frees tty struct for the ttyp2.

After that, getty(8) calls open(2) which in turn calls ptsopen(). But due to tty struct is already destroyed, the following branch works while it should not:

if (tp->t_oproc)
        (void)ttyld_modem(tp, 1)

It happens because freed space is filled with 0xdeadcode pattern (I'm using debug kernel version). As result, we have a crash in ttyld_modem().

How to fix it? It seems that one should not call tty_close() in ptsclose() if tty ref == 1. It not tested however.

What do hackers think about it?

Thank you,
        Sergey.
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to