aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2026-09-28 13:42:54 +0000
committerMark Johnston <markj@FreeBSD.org>2026-09-29 15:56:01 +0000
commit5db05b5dedf38cc9e31f89a9f4df9abb5cb1b539 (patch)
treeef0b397ecc79de93bbc823f38abc7ab4c1f3271f
parent0ee32bf5318dd3221111d76df079ef99f4346178 (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.c3
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)