From: Matthew Dillon Date: Fri, 29 Jul 2011 08:12:08 +0000 (-0700) Subject: kernel - Fix a small race in the umtx code X-Git-Tag: v2.12.0~273 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/369ba561fd5552e7b52e722210befbd970fc3124 kernel - Fix a small race in the umtx code * Add an additional check after registering the vm_page action before actually going to sleep, closing a potential vm_token race. --- diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index c3c3904780..d7137c11db 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -120,7 +120,8 @@ sys_umtx_sleep(struct umtx_sleep_args *uap) * being woken up. */ lwkt_gettoken(&vm_token); - m = vm_fault_page_quick((vm_offset_t)uap->ptr, VM_PROT_READ|VM_PROT_WRITE, &error); + m = vm_fault_page_quick((vm_offset_t)uap->ptr, + VM_PROT_READ|VM_PROT_WRITE, &error); if (m == NULL) { error = EFAULT; goto done; @@ -143,8 +144,12 @@ sys_umtx_sleep(struct umtx_sleep_args *uap) if (*(int *)(lwbuf_kva(lwb) + offset) == uap->value) { vm_page_init_action(m, &action, umtx_sleep_page_action_cow, waddr); vm_page_register_action(&action, VMEVENT_COW); - error = tsleep(waddr, PCATCH | PINTERLOCKED | PDOMAIN_UMTX, - "umtxsl", timeout); + if (*(int *)(lwbuf_kva(lwb) + offset) == uap->value) { + error = tsleep(waddr, PCATCH | PINTERLOCKED | PDOMAIN_UMTX, + "umtxsl", timeout); + } else { + error = EBUSY; + } vm_page_unregister_action(&action); } else { error = EBUSY;