umtx: shm: Fix use-after-free due to multiple drops of the registry reference
umtx_shm_unref_reg_locked() would unconditionally drop the "registry"
reference, tied to USHMF_LINKED.
This is not a problem for caller umtx_shm_object_terminated(), which
operates under the 'umtx_shm_lock' lock end-to-end, but it is for
indirect caller umtx_shm(), which drops the lock between
umtx_shm_find_reg() and the call to umtx_shm_unref_reg(true) that
deregisters the umtx shared region (from 'umtx_shm_registry';
umtx_shm_find_reg() only finds registered shared mutexes).
Thus, two concurrent user-space callers of _umtx_op() with UMTX_OP_SHM
and flags UMTX_SHM_DESTROY, both progressing past umtx_shm_find_reg()
but before umtx_shm_unref_reg(true), would then decrease twice the
reference count for the single reference standing for the shared mutex's
registration.
Reported by: Synacktiv
Reviewed by: kib
Approved by: emaste (mentor)
Security: FreeBSD-SA-24:14.umtx
Security: CVE-2024-43102
Security: CAP-01
Sponsored by: The Alpha-Omega Project
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D46126
(cherry picked from commit 62f40433ab47ad4a9694a22a0313d57661502ca1)
(cherry picked from commit be7dc4613909e528e8b4ea8aaa3ae3aa62bec1ed)
Approved by: so