diff options
| author | thorpej <thorpej@NetBSD.org> | 2022-07-19 01:03:05 +0000 |
|---|---|---|
| committer | thorpej <thorpej@NetBSD.org> | 2022-07-19 01:03:05 +0000 |
| commit | 44145d4d5c820f3d6d5f7b23897118b8182dffdc (patch) | |
| tree | 35c4b389eb28bf6f13c212d1b482c59a06bbd5ee /sys/dev | |
| parent | b81746b7585b54a103621b0083e5638ec232cc3e (diff) | |
Fix a problem whereby detaching a device that has open kevent
registrations can result in a UAF: When a device detaches, it
calls seldestroy(), which calls knote_fini(), and when that
returns, the softc that contained the selinfo and klist are freed.
However, any knotes that were registered still linger on with the
kq descriptor they're were associated with, and when the file
descriptors close, those knotes will be f_detach'd, which will
call into the driver instance that no longer exists.
Address this problem by adding a "foplock" mutex to the knote.
This foplock must be held when calling into filter_attach(),
filter_detach(), and filter_event() (XXX not filter_touch();
see code for details). Now, in klist_fini(), for each knote
that is on the klist that's about to be blown away, acquire
the foplock, replace the knote's filterops with a do-nothing
stub, and release the foplock.
The end result is that:
==> The foplock ensures that calls into filter_*() will get EITHER
the real backing object's filterops OR the nop stubs.
==> Holing the foplock across the filter_*() calls ensures that
klist_fini() will not complete until there are no callers inside
the filterops that are about to be blown away.
Diffstat (limited to 'sys/dev')
0 files changed, 0 insertions, 0 deletions
