Descripción
En Linux kernel se resolvió la siguiente vulnerabilidad: ceph: fix UAF in check_new_map() on session freed during unlock check_new_map() recorre mdsc->sessions[] y, para cada sesión activa, libera mdsc->mutex para realizar operaciones por sesión. La ruta de cierre forzado (rango eliminado del mapa) toma correctamente una referencia sobre s mediante ceph_get_mds_session() antes de liberar mdsc->mutex, pero otras tres rutas no lo hacen: Ruta A (dirección cambiada): mutex_unlock → mutex_lock(&s->s_mutex) Ruta B (reconexión): mutex_unlock → send_mds_reconnect(mdsc, s) Ruta C (transición a activo): mutex_unlock → mutex_lock(&s->s_mutex) Sin la referencia adicional, otro hilo puede adquirir mdsc->mutex durante la ventana de desbloqueo, llamar a __unregister_session(), que libera la última referencia sobre s, y liberarla. El hilo original accede entonces a memoria liberada mediante s->s_mutex. La corrección agrega ceph_get_mds_session(s) antes de cada mutex_unlock y ceph_put_mds_session(s) después del mutex_lock correspondiente, siguiendo el patrón ya utilizado en la ruta de cierre forzado. Secuencia de la condición de carrera (Ruta A): el hilo A (check_new_map), que mantiene mdsc->mutex, obtiene s = mdsc->sessions[i] (refcount == 1, mantenido solo por el arreglo sessions[]) y ejecuta mutex_unlock(&mdsc->mutex); el hilo B (otra actualización del mapa o cierre de sesión) adquiere mdsc->mutex, ejecuta __unregister_session(mdsc, s), sessions[i] = NULL, ceph_put_mds_session(s) (refcount: 1 -> 0) y kfree(s); luego el hilo A ejecuta mutex_lock(&s->s_mutex), lo que produce un uso después de liberar memoria sobre s->s_mutex.
Qué hacer
Revisa si usas el producto afectado y en qué versión, y aplica la actualización o la mitigación que indique el aviso del fabricante. CISA no ha confirmado que se esté explotando; si eso cambia, esta ficha pasa a «explotada» y te avisamos en el boletín.
Versiones afectadas
- Linux Afectadas: 2f2dc053404febedc9c273452d9d518fb31fde72 y anteriores a 989343b7ee5b1a08778be0c7c4bf6030d3910807 · 2f2dc053404febedc9c273452d9d518fb31fde72 y anteriores a 352a278d5a1965aae3f817ce5d24a67ee42d45d1 · 2f2dc053404febedc9c273452d9d518fb31fde72 y anteriores a 820871e9dbeecd2533c4c5f5d91878ceaf02324c · 2f2dc053404febedc9c273452d9d518fb31fde72 y anteriores a 9646dfee880730aae4b379a4b8ee6c88ac735acd · 2f2dc053404febedc9c273452d9d518fb31fde72 y anteriores a 21d5be092d947f8d83f76f7ebf3989e7e9230a98 · 2f2dc053404febedc9c273452d9d518fb31fde72 y anteriores a ee611a7509554c4ca1f54f6aefe592fb1df7ea70
- Linux Afectadas: 2.6.34 No afectadas: 6.1.191 · 6.6.160 · 6.12.114 · 6.18.57 · 7.2.4 · 7.3
Según el registro de la vulnerabilidad en CVE.org, tal como lo publicó el fabricante. Confirma tu versión exacta en el aviso del fabricante.
Referencias
- Referencia en git.kernel.orggit.kernel.org/stable/c/989343b7ee5b1a08778be0c7c4bf6030d3910807
- Referencia en git.kernel.orggit.kernel.org/stable/c/352a278d5a1965aae3f817ce5d24a67ee42d45d1
- Referencia en git.kernel.orggit.kernel.org/stable/c/820871e9dbeecd2533c4c5f5d91878ceaf02324c
- Referencia en git.kernel.orggit.kernel.org/stable/c/9646dfee880730aae4b379a4b8ee6c88ac735acd
- Referencia en git.kernel.orggit.kernel.org/stable/c/21d5be092d947f8d83f76f7ebf3989e7e9230a98
- Referencia en git.kernel.orggit.kernel.org/stable/c/ee611a7509554c4ca1f54f6aefe592fb1df7ea70
Ver el texto original en inglés (CVE.org)
ceph: fix UAF in check_new_map() on session freed during unlock
In the Linux kernel, the following vulnerability has been resolved: ceph: fix UAF in check_new_map() on session freed during unlock check_new_map() iterates mdsc->sessions[] and for each active session drops mdsc->mutex to perform per-session operations. The forced-close path (rank removed from map) correctly takes a reference on s via ceph_get_mds_session() before releasing mdsc->mutex, but three other paths do not: Path A (address changed): mutex_unlock → mutex_lock(&s->s_mutex) Path B (reconnect): mutex_unlock → send_mds_reconnect(mdsc, s) Path C (active transition): mutex_unlock → mutex_lock(&s->s_mutex) Without the extra reference, another thread can acquire mdsc->mutex during the unlock window, call __unregister_session() which drops the last reference on s, and free it. The original thread then accesses freed memory via s->s_mutex. Fix by adding ceph_get_mds_session(s) before each mutex_unlock and ceph_put_mds_session(s) after the corresponding mutex_lock, matching the pattern already used in the forced-close path. Race timeline (Path A): Thread A (check_new_map) Thread B (another map update holds mdsc->mutex or session teardown) -------------------------- -------------------------- s = mdsc->sessions[i] (refcount == 1, held only by sessions[] array) mutex_unlock(&mdsc->mutex) ---> acquires mdsc->mutex __unregister_session(mdsc, s) sessions[i] = NULL ceph_put_mds_session(s) refcount: 1 -> 0 kfree(s) <--- freed! mutex_lock(&s->s_mutex) UAF on freed s->s_mutex