X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/b0d623f7f2ae71ed96e60569f61f9a9a27016e80..9d749ea394c01276fa19e397e70f46858e849c76:/osfmk/vm/vm_swapfile_pager.c diff --git a/osfmk/vm/vm_swapfile_pager.c b/osfmk/vm/vm_swapfile_pager.c index db8943367..f24307d74 100644 --- a/osfmk/vm/vm_swapfile_pager.c +++ b/osfmk/vm/vm_swapfile_pager.c @@ -64,12 +64,7 @@ * the disk blocks they were allocated. The "super-user" could see the * contents of free blocks anyway, so this is not a new security issue but * it may be perceive as one. - * * ENCRYPTED SWAP: - * When swap is encrypted, one does not expect to find any clear contents - * in the swap files. Since unused blocks are not scrubbed, they could still - * contain clear contents. If these contents are visible through a mapping - * of the swap file, it makes it look like swap is not really encrypted. - * + * * We can't legitimately prevent a user process with appropriate privileges * from mapping a swap file, but we can prevent it from accessing its actual * contents. @@ -130,6 +125,7 @@ const struct memory_object_pager_ops swapfile_pager_ops = { swapfile_pager_synchronize, swapfile_pager_map, swapfile_pager_last_unmap, + NULL, /* data_reclaim */ "swapfile pager" }; @@ -138,17 +134,17 @@ const struct memory_object_pager_ops swapfile_pager_ops = { * the "swapfile" EMM. */ typedef struct swapfile_pager { - struct ipc_object_header pager_header; /* fake ip_kotype() */ - memory_object_pager_ops_t pager_ops; /* == &swapfile_pager_ops */ + /* mandatory generic header */ + struct memory_object swp_pgr_hdr; + + /* pager-specific data */ queue_chain_t pager_queue; /* next & prev pagers */ unsigned int ref_count; /* reference count */ boolean_t is_ready; /* is this pager ready ? */ boolean_t is_mapped; /* is this pager mapped ? */ - memory_object_control_t pager_control; /* mem object control handle */ struct vnode *swapfile_vnode;/* the swapfile's vnode */ } *swapfile_pager_t; #define SWAPFILE_PAGER_NULL ((swapfile_pager_t) NULL) -#define pager_ikot pager_header.io_bits /* * List of memory objects managed by this EMM. @@ -234,7 +230,7 @@ swapfile_pager_init( memory_object_control_reference(control); - pager->pager_control = control; + pager->swp_pgr_hdr.mo_control = control; attributes.copy_strategy = MEMORY_OBJECT_COPY_DELAY; attributes.cluster_size = (1 << (PAGE_SHIFT)); @@ -342,7 +338,7 @@ swapfile_pager_data_request( /* * Gather in a UPL all the VM pages requested by VM. */ - mo_control = pager->pager_control; + mo_control = pager->swp_pgr_hdr.mo_control; upl_size = length; upl_flags = @@ -354,7 +350,7 @@ swapfile_pager_data_request( pl_count = 0; kr = memory_object_upl_request(mo_control, offset, upl_size, - &upl, NULL, NULL, upl_flags); + &upl, NULL, NULL, upl_flags, VM_KERN_MEMORY_OSFMK); if (kr != KERN_SUCCESS) { retval = kr; goto done; @@ -373,14 +369,16 @@ swapfile_pager_data_request( PAGE_SIZE_64, 0, 0, + VM_MAP_KERNEL_FLAGS_NONE, + VM_KERN_MEMORY_NONE, &map_entry); if (kr != KERN_SUCCESS) { vm_object_deallocate(kernel_object); retval = kr; goto done; } - map_entry->object.vm_object = kernel_object; - map_entry->offset = kernel_mapping - VM_MIN_KERNEL_ADDRESS; + VME_OBJECT_SET(map_entry, kernel_object); + VME_OFFSET_SET(map_entry, kernel_mapping - VM_MIN_KERNEL_ADDRESS); vm_map_unlock(kernel_map); dst_vaddr = CAST_DOWN(vm_offset_t, kernel_mapping); dst_ptr = (char *) dst_vaddr; @@ -407,12 +405,19 @@ swapfile_pager_data_request( dst_pnum = (ppnum_t) upl_phys_page(upl_pl, (int)(cur_offset / PAGE_SIZE)); assert(dst_pnum != 0); - pmap_enter(kernel_pmap, - kernel_mapping, - dst_pnum, - VM_PROT_READ | VM_PROT_WRITE, - dst_object->wimg_bits & VM_WIMG_MASK, - TRUE); + retval = pmap_enter(kernel_pmap, + kernel_mapping, + dst_pnum, + VM_PROT_READ | VM_PROT_WRITE, + VM_PROT_NONE, + 0, + TRUE); + + assert(retval == KERN_SUCCESS); + + if (retval != KERN_SUCCESS) { + goto done; + } memset(dst_ptr, '\0', PAGE_SIZE); /* add an end-of-line to keep line counters happy */ @@ -540,7 +545,7 @@ swapfile_pager_terminate_internal( } /* trigger the destruction of the memory object */ - memory_object_destroy(pager->pager_control, 0); + memory_object_destroy(pager->swp_pgr_hdr.mo_control, 0); } /* @@ -580,9 +585,9 @@ swapfile_pager_deallocate_internal( * pager structure. */ lck_mtx_unlock(&swapfile_pager_lock); - if (pager->pager_control != MEMORY_OBJECT_CONTROL_NULL) { - memory_object_control_deallocate(pager->pager_control); - pager->pager_control = MEMORY_OBJECT_CONTROL_NULL; + if (pager->swp_pgr_hdr.mo_control != MEMORY_OBJECT_CONTROL_NULL) { + memory_object_control_deallocate(pager->swp_pgr_hdr.mo_control); + pager->swp_pgr_hdr.mo_control = MEMORY_OBJECT_CONTROL_NULL; } kfree(pager, sizeof (*pager)); pager = SWAPFILE_PAGER_NULL; @@ -631,21 +636,13 @@ swapfile_pager_terminate( */ kern_return_t swapfile_pager_synchronize( - memory_object_t mem_obj, - memory_object_offset_t offset, - memory_object_size_t length, + __unused memory_object_t mem_obbj, + __unused memory_object_offset_t offset, + __unused memory_object_size_t length, __unused vm_sync_t sync_flags) { - swapfile_pager_t pager; - - PAGER_DEBUG(PAGER_ALL, ("swapfile_pager_synchronize: %p\n", mem_obj)); - - pager = swapfile_pager_lookup(mem_obj); - - memory_object_synchronize_completed(pager->pager_control, - offset, length); - - return KERN_SUCCESS; + panic("swapfile_pager_synchronize: memory_object_synchronize no longer supported\n"); + return (KERN_FAILURE); } /* @@ -726,8 +723,8 @@ swapfile_pager_lookup( { swapfile_pager_t pager; - pager = (swapfile_pager_t) mem_obj; - assert(pager->pager_ops == &swapfile_pager_ops); + assert(mem_obj->mo_pager_ops == &swapfile_pager_ops); + __IGNORE_WCASTALIGN(pager = (swapfile_pager_t) mem_obj); assert(pager->ref_count > 0); return pager; } @@ -752,12 +749,13 @@ swapfile_pager_create( * we reserve the second word in the object for a fake ip_kotype * setting - that will tell vm_map to use it as a memory object. */ - pager->pager_ops = &swapfile_pager_ops; - pager->pager_ikot = IKOT_MEMORY_OBJECT; + pager->swp_pgr_hdr.mo_ikot = IKOT_MEMORY_OBJECT; + pager->swp_pgr_hdr.mo_pager_ops = &swapfile_pager_ops; + pager->swp_pgr_hdr.mo_control = MEMORY_OBJECT_CONTROL_NULL; + pager->is_ready = FALSE;/* not ready until it has a "name" */ pager->ref_count = 1; /* setup reference */ pager->is_mapped = FALSE; - pager->pager_control = MEMORY_OBJECT_CONTROL_NULL; pager->swapfile_vnode = vp; lck_mtx_lock(&swapfile_pager_lock); @@ -870,7 +868,10 @@ swapfile_pager_control( { swapfile_pager_t pager; + if (mem_obj == MEMORY_OBJECT_NULL || + mem_obj->mo_pager_ops != &swapfile_pager_ops) { + return MEMORY_OBJECT_CONTROL_NULL; + } pager = swapfile_pager_lookup(mem_obj); - - return pager->pager_control; + return pager->swp_pgr_hdr.mo_control; }