Skip to content

Commit

Permalink
tty: delete knotes when TTY is revoked
Browse files Browse the repository at this point in the history
Do not clear knotes from the TTY until it gets dealloc'ed, unless the
TTY is being revoked, in that case delete the knotes when closed is
called on the TTY.

When knotes are cleared from a knlist, those knotes become detached from
the knlist. And when an event is triggered on a detached knote there
isn't an associated knlist and therefore no lock will be taken when the
event is triggered.

This becomes a problem when a detached knote is triggered on a TTY since
the mutex for a TTY is also used as the lock for its knlists. This
scenario ends up calling the TTY event handlers without the TTY lock
being held and tripping on asserts in the event handlers.

PR:             272151
Reviewed by:	kib, markj
Differential Revision:	https://reviews.freebsd.org/D41605

(cherry picked from commit acd5638)
  • Loading branch information
rob-wing authored and markjdb committed Oct 10, 2024
1 parent d10c9c1 commit 3e19aac
Showing 1 changed file with 7 additions and 5 deletions.
12 changes: 7 additions & 5 deletions sys/kern/tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,6 @@ ttydev_leave(struct tty *tp)
ttyoutq_free(&tp->t_outq);
tp->t_outlow = 0;

knlist_clear(&tp->t_inpoll.si_note, 1);
knlist_clear(&tp->t_outpoll.si_note, 1);

if (!tty_gone(tp))
ttydevsw_close(tp);

Expand Down Expand Up @@ -370,7 +367,7 @@ done: tp->t_flags &= ~TF_OPENCLOSE;

static int
ttydev_close(struct cdev *dev, int fflag, int devtype __unused,
struct thread *td __unused)
struct thread *td)
{
struct tty *tp = dev->si_drv1;

Expand All @@ -393,8 +390,11 @@ ttydev_close(struct cdev *dev, int fflag, int devtype __unused,
}

/* If revoking, flush output now to avoid draining it later. */
if (fflag & FREVOKE)
if ((fflag & FREVOKE) != 0) {
tty_flush(tp, FWRITE);
knlist_delete(&tp->t_inpoll.si_note, td, 1);
knlist_delete(&tp->t_outpoll.si_note, td, 1);
}

tp->t_flags &= ~TF_EXCLUDE;

Expand Down Expand Up @@ -1121,6 +1121,8 @@ tty_dealloc(void *arg)
ttyoutq_free(&tp->t_outq);
seldrain(&tp->t_inpoll);
seldrain(&tp->t_outpoll);
knlist_clear(&tp->t_inpoll.si_note, 0);
knlist_clear(&tp->t_outpoll.si_note, 0);
knlist_destroy(&tp->t_inpoll.si_note);
knlist_destroy(&tp->t_outpoll.si_note);

Expand Down

0 comments on commit 3e19aac

Please sign in to comment.