Summary: | panic: use-after-free tty race condition | ||
---|---|---|---|
Product: | Base System | Reporter: | Jake Freeland <jake> |
Component: | kern | Assignee: | Robert Wing <rew> |
Status: | Open --- | ||
Severity: | Affects Many People | CC: | dch, dchagin, emaste, freebsd, grahamperrin, kevans, markj, rew |
Priority: | --- | Keywords: | crash |
Version: | CURRENT | Flags: | linimon:
mfc-stable14?
linimon: mfc-stable13? |
Hardware: | amd64 | ||
OS: | Any | ||
See Also: | https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=269520 |
Description
Jake Freeland
2023-06-22 16:30:42 UTC
I guess the implication is that we're hitting https://cgit.freebsd.org/src/tree/sys/kern/kern_event.c#n1732 with a NULL kn->kn_knlist, in which case the previous kn_list_lock() was effectively a nop and we're not meeting the invariant described in kqueue(9): The knlist_*() family of functions are for managing knotes associated with an object. A knlist is not required, but is commonly used. If used, the knlist must be initialized with either knlist_init() or knlist_init_mtx(). The knlist structure may be embedded into the object structure. *The lock will be held over f_event calls.* Maybe dchagin@ or markj@ can comment a little further on this one. The issue seems to be caused by knlist_clear() with the way it sets up the knote with EV_ONESHOT. The event for the knote is triggered after the TTY is revoked and the thread no longer holds the TTY lock when the knote event is called. I'd halfway assume that knotes shouldn't be triggered if the TTY was revoked, which might look something like: https://people.freebsd.org/~rew/tf-revoke.patch or maybe it makes sense to delete the knotes when the TTY is not opened? something like: https://people.freebsd.org/~rew/tty-knote.patch or...some other behavior is expected? either way, both of the patches above prevented the panic from occurring. To reproduce, spin up a vm and execute the following: - launch nvim - suspend nvim (ctrl-z) - poweroff (panic) https://reviews.freebsd.org/D41605 I'm not sure this is the best fix but, I'm guessing we are going to get more reports about this in the future as I've hit it randomly a few times now. A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=acd5638e268a6706f6b7ad84947a8425e8d51ef7 commit acd5638e268a6706f6b7ad84947a8425e8d51ef7 Author: Robert Wing <rew@FreeBSD.org> AuthorDate: 2023-12-19 00:40:46 +0000 Commit: Robert Wing <rew@FreeBSD.org> CommitDate: 2023-12-19 00:40:46 +0000 tty: delete knotes when TTY is revoked 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 sys/kern/tty.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) ^Triage: assign to committer that resolved; set possible MFC flags. |