diff options
| author | Mark Johnston <markj@FreeBSD.org> | 2026-09-28 13:42:54 +0000 |
|---|---|---|
| committer | Mark Johnston <markj@FreeBSD.org> | 2026-09-29 15:56:01 +0000 |
| commit | 5db05b5dedf38cc9e31f89a9f4df9abb5cb1b539 (patch) | |
| tree | ef0b397ecc79de93bbc823f38abc7ab4c1f3271f | |
| parent | 0ee32bf5318dd3221111d76df079ef99f4346178 (diff) | |
kqueue: Fix a potential OOB access in kqueue_fork_copy_knote()
Here, fdp points to the new fdtable, copied from that of the parent
process. There is a window after the fdtable is copied, and before
kqueue_fork_copy_knote() runs, where a different thread in the parent
could have grown the parent's fdtable and registered a knote with ident
larger than the size of the child's fdtable. This race can lead to an
out-of-bounds read.
Add a bounds check for this case; skip the knote if it is referencing a
non-existent file.
Approved by: so
Security: FreeBSD-SA-26:65.kqueue
Security: CVE-2026-58100
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D59916
| -rw-r--r-- | sys/kern/kern_event.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 32e2e6e69d7e..5bfa6f8a800e 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -3108,7 +3108,8 @@ kqueue_fork_copy_knote(struct kqueue *kq, struct kqueue *kq1, struct knote *kn, } fop = kn->kn_fop; if (fop->f_copy == NULL || (fop->f_isfd && - fdp->fd_files->fdt_ofiles[kn->kn_kevent.ident].fde_file == NULL)) + ((unsigned int)fdp->fd_files->fdt_nfiles <= kn->kn_kevent.ident || + fdp->fd_files->fdt_ofiles[kn->kn_kevent.ident].fde_file == NULL))) return; error = kqueue_expand(kq1, fop, kn->kn_kevent.ident, M_WAITOK); if (error != 0) |
