kqueue: on process exit, force-clear its registered signal events

Normally, process already has all its kqueue fds destroyed at the moment
p_klist is detached in exit flow. But, if the process was created with
rfork(2) with shared file descriptors, its signal knotes can survive.
Then, knlist_detach() does not destroy non-empty knlist. Later, when
owning kqueue is closed, we access freed (or rather, reused, because
struct proc is type-stable) memory by referencing p->p_klist from such
knote.

Handle this situation by deleting all knotes hanging from p_klist.

PR:	275286
Reviewed by:	markj
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D42745
This commit is contained in:
Konstantin Belousov 2023-11-24 08:41:58 +02:00
parent 50335b1ae4
commit 393ac29f0b

View file

@ -985,6 +985,7 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options)
proc_id_clear(PROC_ID_PID, p->p_pid);
PROC_LOCK(p);
knlist_delete(p->p_klist, td, 1);
knlist_detach(p->p_klist);
p->p_klist = NULL;
PROC_UNLOCK(p);