From 339772b0039724319baf5bbdb3bb70dfd551f3d3 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 30 Jul 2011 14:13:57 +0000 Subject: [PATCH] Fix a race in the device pager allocation. If another thread won and allocated the device pager for the given handle, then the object fictitious pages list and the object membership in the global object list still need to be initialized. Otherwise, dev_pager_dealloc() will traverse uninitialized pointers. Reported and tested by: pho Reviewed by: jhb Approved by: re (kensmith) MFC after: 1 week --- sys/vm/device_pager.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c index 411482a3cc2..d46d17055b6 100644 --- a/sys/vm/device_pager.c +++ b/sys/vm/device_pager.c @@ -147,6 +147,7 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, object1 = vm_object_allocate(OBJT_DEVICE, pindex); object1->flags |= OBJ_COLORED; object1->pg_color = atop(paddr) - OFF_TO_IDX(off - PAGE_SIZE); + TAILQ_INIT(&object1->un_pager.devp.devp_pglist); mtx_lock(&dev_pager_mtx); object = vm_pager_object_lookup(&dev_pager_object_list, handle); if (object != NULL) { @@ -159,7 +160,6 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, object = object1; object1 = NULL; object->handle = handle; - TAILQ_INIT(&object->un_pager.devp.devp_pglist); TAILQ_INSERT_TAIL(&dev_pager_object_list, object, pager_object_list); } @@ -169,7 +169,14 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, } mtx_unlock(&dev_pager_mtx); dev_relthread(dev, ref); - vm_object_deallocate(object1); + if (object1 != NULL) { + object1->handle = object1; + mtx_lock(&dev_pager_mtx); + TAILQ_INSERT_TAIL(&dev_pager_object_list, object1, + pager_object_list); + mtx_unlock(&dev_pager_mtx); + vm_object_deallocate(object1); + } return (object); }