ipc_pset_signal ignores the kqueue in-flux protocol that knote() implements
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 45/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Tranquilo
- Stack tecnológico
- c
- Área
- operating-systems
Línea de trabajo
Read sys/kern/kern_event.c, especially knote(), the kqueue_scan() paths around lines 2220 and 2243, and ipc_pset_signal(). First instrument activations where kn_in_flux(kn) is set and KN_SCAN is clear, then reproduce the failure and check the counter. If proceeding with the fix, preserve the KN_SCAN exception and verify the in-flux guard prevents unsafe enqueueing.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
ipc_pset_signal() hand-rolls knote activation and does not implement the
in-flux protocol that FreeBSD's own knote() implements explicitly. It can
therefore activate and enqueue a knote that the kqueue core has taken out of
the queue and marked in flux — including one that is being dropped and freed.
Found by reading sys/kern/kern_event.c from the base tree (stock
releng/15.1; no patch in patches/ touches it).
The protocol being violated
knote() skips in-flux knotes, and the comment says exactly why the one
exception is safe:
2585 SLIST_FOREACH_SAFE(kn, &list->kl_list, kn_selnext, tkn) {
2586 kq = kn->kn_kq;
2587 KQ_LOCK(kq);
2588 if (kn_in_flux(kn) && (kn->kn_status & KN_SCAN) == 0) {
2589 /*
2590 * Do not process the influx notes, except for
2591 * the influx coming from the kq unlock in the
2592 * kqueue_scan(). In the later case, we do
2593 * not interfere with the scan, since the code
2594 * fragment in kqueue_scan() locks the knlist,
2595 * and cannot proceed until we finished.
2596 */
2597 KQ_UNLOCK(kq);
2598 }
ipc_pset_signal() has no equivalent. It tests only KN_QUEUED | KN_DISABLED:
(kn)->kn_status |= KN_ACTIVE;
if (((kn)->kn_status & (KN_QUEUED | KN_DISABLED)) == 0)
mach_knote_enqueue(kn);
Why it cannot simply call knote()
filt_machport() has side effects — it performs the receive into
current_thread()'s ith_* state. Called from knote() on the sender's
thread it would deliver the notification into the wrong thread entirely. That
is presumably why the activation was open-coded. The influx check was not
carried across with it.
Worst case
kqueue_scan()'s EV_ONESHOT path puts a knote in flux without KN_SCAN
and then frees it:
2220 } else if ((kn->kn_flags & EV_ONESHOT) == EV_ONESHOT) {
2221 kn->kn_status &= ~KN_QUEUED;
2222 kn_enter_flux(kn);
2223 kq->kq_count--;
2224 KQ_UNLOCK(kq);
...
2230 knote_drop(kn, td);
Between 2224 and the drop, ipc_pset_signal() may observe KN_QUEUED clear,
TAILQ_INSERT_TAIL the knote onto kq_head and bump kq_count — on a knote
that is then freed. filt_machport() sets EV_ONESHOT itself on both its
EV_EOF and translate-failure paths, so this is reachable.
A second shape: the zero-return path at 2243 clears KN_QUEUED and
decrements kq_count without a TAILQ_REMOVE, because the knote was
already unlinked when the scan dequeued it. A concurrent re-insertion by
ipc_pset_signal() leaves the knote physically on kq_head while marked
not-queued, with kq_count under-counted.
Relationship to the wedge
Not yet established, and should not be assumed. Every stage of the delivery
path has now measured clean (see #145), so an activation that is dropped or
mis-queued at the kqueue boundary is a live candidate — but three previous
candidates in this area looked equally sound and measured zero.
Instrument before fixing. Count activations landing on a knote with
kn_in_flux(kn) set and KN_SCAN clear — precisely the case knote()
skips. If that counter stays zero while the failure reproduces, this is a
latent correctness bug worth fixing on its own merits but not the wedge.
Fix
Add the same guard knote() uses, keeping the KN_SCAN exception, which is
safe here for the same documented reason: kqueue_scan() holds the knlist
lock across f_event, and ipc_pset_signal() takes that same lock
(ips_note_lock, exclusive via kn_sx_lock on the kqueue side, shared here),
so the two cannot interleave.
- Lenguaje dominante
- C
- Estrellas
- 12
- Forks
- 3
- Merge medio
- 7 h 1 min
- PR fusionados (30 d)
- 7
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de nextbsd/nextbsd-kernel
-
area:bluetooth bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
nextbsd/nextbsd-kernel#236 ·
Los mantenedores suelen responder en 1 día
-
area:vm bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
nextbsd/nextbsd-kernel#226 ·
Los mantenedores suelen responder en 1 día
-
area:network enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
nextbsd/nextbsd-kernel#53 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
nextbsd/nextbsd-kernel#254 ·
Los mantenedores suelen responder en 1 día
-
linsysfs: create DRM sysfs nodes for platform-bus GPUs so Linux libdrm finds vc4/v3d on the Pi 5Abiertoarea:linux area:rpi5 enhancement
Dificultad 4/5 3-5 días Aptitud para principiantes 47/100
nextbsd/nextbsd-kernel#248 ·
Los mantenedores suelen responder en 1 día
Todos los issues de nextbsd/nextbsd-kernel
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 66/100
FujiNetWIFI/fujinet-lib#186 ·
Los mantenedores suelen responder en 1 día
-
VIEW_TYPE set for computer playersPosiblemente ocupada @Loobinex la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Los mantenedores suelen responder en 2 días
-
bug
Dificultad 2/5 Menos de una hora Aptitud para principiantes 78/100
brunodev85/winlator-app#90 ·