1/* 2 * Copyright (c) 2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29/* 30 * Make sure we don't accidentally include the external definitions of 31 * the routines we're interposing on below. 32 */ 33#define _vm_map_user_ 34#define _mach_vm_user_ 35#include <mach/mach.h> 36#include <mach/mach_traps.h> 37#undef _vm_map_user_ 38#include <mach/vm_map_internal.h> 39#undef _mach_vm_user_ 40#include <mach/mach_vm_internal.h> 41 42#include "stack_logging_internal.h" 43 44malloc_logger_t *__syscall_logger = NULL; // This may get set by Libc's malloc stack logging initialization code. 45 46kern_return_t 47mach_vm_allocate( 48 mach_port_name_t target, 49 mach_vm_address_t *address, 50 mach_vm_size_t size, 51 int flags) 52{ 53 kern_return_t rv; 54 55 rv = _kernelrpc_mach_vm_allocate_trap(target, address, size, flags); 56 57 if (rv == MACH_SEND_INVALID_DEST) 58 rv = _kernelrpc_mach_vm_allocate(target, address, size, flags); 59 60 if (__syscall_logger) { 61 int userTagFlags = flags & VM_FLAGS_ALIAS_MASK; 62 __syscall_logger(stack_logging_type_vm_allocate | userTagFlags, (uintptr_t)target, (uintptr_t)size, 0, (uintptr_t)*address, 0); 63 } 64 65 return (rv); 66} 67 68kern_return_t 69mach_vm_deallocate( 70 mach_port_name_t target, 71 mach_vm_address_t address, 72 mach_vm_size_t size) 73{ 74 kern_return_t rv; 75 76 rv = _kernelrpc_mach_vm_deallocate_trap(target, address, size); 77 78 if (rv == MACH_SEND_INVALID_DEST) 79 rv = _kernelrpc_mach_vm_deallocate(target, address, size); 80 81 if (__syscall_logger) { 82 __syscall_logger(stack_logging_type_vm_deallocate, (uintptr_t)target, (uintptr_t)address, (uintptr_t)size, 0, 0); 83 } 84 85 return (rv); 86} 87 88kern_return_t 89mach_vm_protect( 90 mach_port_name_t task, 91 mach_vm_address_t address, 92 mach_vm_size_t size, 93 boolean_t set_maximum, 94 vm_prot_t new_protection) 95{ 96 kern_return_t rv; 97 98 rv = _kernelrpc_mach_vm_protect_trap(task, address, size, set_maximum, 99 new_protection); 100 101 if (rv == MACH_SEND_INVALID_DEST) 102 rv = _kernelrpc_mach_vm_protect(task, address, size, 103 set_maximum, new_protection); 104 105 return (rv); 106} 107 108kern_return_t 109vm_allocate( 110 mach_port_name_t task, 111 vm_address_t *address, 112 vm_size_t size, 113 int flags) 114{ 115 kern_return_t rv; 116 mach_vm_address_t mach_addr; 117 118 mach_addr = (mach_vm_address_t)*address; 119 rv = mach_vm_allocate(task, &mach_addr, size, flags); 120#if defined(__LP64__) 121 *address = mach_addr; 122#else 123 *address = (vm_address_t)(mach_addr & ((vm_address_t)-1)); 124#endif 125 126 return (rv); 127} 128 129kern_return_t 130vm_deallocate( 131 mach_port_name_t task, 132 vm_address_t address, 133 vm_size_t size) 134{ 135 kern_return_t rv; 136 137 rv = mach_vm_deallocate(task, address, size); 138 139 return (rv); 140} 141 142kern_return_t 143vm_protect( 144 mach_port_name_t task, 145 vm_address_t address, 146 vm_size_t size, 147 boolean_t set_maximum, 148 vm_prot_t new_protection) 149{ 150 kern_return_t rv; 151 152 rv = mach_vm_protect(task, address, size, set_maximum, new_protection); 153 154 return (rv); 155} 156 157kern_return_t 158mach_vm_map( 159 mach_port_name_t target, 160 mach_vm_address_t *address, 161 mach_vm_size_t size, 162 mach_vm_offset_t mask, 163 int flags, 164 mem_entry_name_port_t object, 165 memory_object_offset_t offset, 166 boolean_t copy, 167 vm_prot_t cur_protection, 168 vm_prot_t max_protection, 169 vm_inherit_t inheritance) 170{ 171 kern_return_t rv = MACH_SEND_INVALID_DEST; 172 173 if (object == MEMORY_OBJECT_NULL && max_protection == VM_PROT_ALL && 174 inheritance == VM_INHERIT_DEFAULT) 175 rv = _kernelrpc_mach_vm_map_trap(target, address, size, mask, flags, 176 cur_protection); 177 178 if (rv == MACH_SEND_INVALID_DEST) 179 rv = _kernelrpc_mach_vm_map(target, address, size, mask, flags, object, 180 offset, copy, cur_protection, max_protection, inheritance); 181 182 if (__syscall_logger) { 183 int eventTypeFlags = stack_logging_type_vm_allocate | stack_logging_type_mapped_file_or_shared_mem; 184 int userTagFlags = flags & VM_FLAGS_ALIAS_MASK; 185 __syscall_logger(eventTypeFlags | userTagFlags, (uintptr_t)target, (uintptr_t)size, 0, (uintptr_t)*address, 0); 186 } 187 188 return (rv); 189} 190 191kern_return_t 192mach_vm_remap( 193 mach_port_name_t target, 194 mach_vm_address_t *address, 195 mach_vm_size_t size, 196 mach_vm_offset_t mask, 197 int flags, 198 mach_port_name_t src_task, 199 mach_vm_address_t src_address, 200 boolean_t copy, 201 vm_prot_t *cur_protection, 202 vm_prot_t *max_protection, 203 vm_inherit_t inheritance) 204{ 205 kern_return_t rv; 206 207 rv = _kernelrpc_mach_vm_remap(target, address, size, mask, flags, 208 src_task, src_address, copy, cur_protection, max_protection, 209 inheritance); 210 211 if (__syscall_logger) { 212 int eventTypeFlags = stack_logging_type_vm_allocate | stack_logging_type_mapped_file_or_shared_mem; 213 int userTagFlags = flags & VM_FLAGS_ALIAS_MASK; 214 __syscall_logger(eventTypeFlags | userTagFlags, (uintptr_t)target, (uintptr_t)size, 0, (uintptr_t)*address, 0); 215 } 216 217 return (rv); 218} 219 220kern_return_t 221mach_vm_read( 222 mach_port_name_t target, 223 mach_vm_address_t address, 224 mach_vm_size_t size, 225 vm_offset_t *data, 226 mach_msg_type_number_t *dataCnt) 227{ 228 kern_return_t rv; 229 230 rv = _kernelrpc_mach_vm_read(target, address, size, data, dataCnt); 231 232 if (__syscall_logger) { 233 int eventTypeFlags = stack_logging_type_vm_allocate | stack_logging_type_mapped_file_or_shared_mem; 234 // The target argument is the remote task from which data is being read, 235 // so pass mach_task_self() as the destination task receiving the allocation. 236 __syscall_logger(eventTypeFlags, (uintptr_t)mach_task_self(), (uintptr_t)*dataCnt, 0, *data, 0); 237 } 238 239 return (rv); 240} 241 242kern_return_t 243vm_map( 244 mach_port_name_t target, 245 vm_address_t *address, 246 vm_size_t size, 247 vm_offset_t mask, 248 int flags, 249 mem_entry_name_port_t object, 250 vm_offset_t offset, 251 boolean_t copy, 252 vm_prot_t cur_protection, 253 vm_prot_t max_protection, 254 vm_inherit_t inheritance) 255{ 256 kern_return_t rv; 257 258 rv = _kernelrpc_vm_map(target, address, size, mask, flags, object, 259 offset, copy, cur_protection, max_protection, inheritance); 260 261 if (__syscall_logger) { 262 int eventTypeFlags = stack_logging_type_vm_allocate | stack_logging_type_mapped_file_or_shared_mem; 263 int userTagFlags = flags & VM_FLAGS_ALIAS_MASK; 264 __syscall_logger(eventTypeFlags | userTagFlags, (uintptr_t)target, (uintptr_t)size, 0, (uintptr_t)*address, 0); 265 } 266 267 return (rv); 268} 269 270kern_return_t 271vm_remap( 272 mach_port_name_t target, 273 vm_address_t *address, 274 vm_size_t size, 275 vm_offset_t mask, 276 int flags, 277 mach_port_name_t src_task, 278 vm_address_t src_address, 279 boolean_t copy, 280 vm_prot_t *cur_protection, 281 vm_prot_t *max_protection, 282 vm_inherit_t inheritance) 283{ 284 kern_return_t rv; 285 286 rv = _kernelrpc_vm_remap(target, address, size, mask, flags, 287 src_task, src_address, copy, cur_protection, max_protection, 288 inheritance); 289 290 if (__syscall_logger) { 291 int eventTypeFlags = stack_logging_type_vm_allocate | stack_logging_type_mapped_file_or_shared_mem; 292 int userTagFlags = flags & VM_FLAGS_ALIAS_MASK; 293 __syscall_logger(eventTypeFlags | userTagFlags, (uintptr_t)target, (uintptr_t)size, 0, (uintptr_t)*address, 0); 294 } 295 296 return (rv); 297} 298 299kern_return_t 300vm_read( 301 mach_port_name_t target, 302 vm_address_t address, 303 vm_size_t size, 304 vm_offset_t *data, 305 mach_msg_type_number_t *dataCnt) 306{ 307 kern_return_t rv; 308 309 rv = _kernelrpc_vm_read(target, address, size, data, dataCnt); 310 311 if (__syscall_logger) { 312 int eventTypeFlags = stack_logging_type_vm_allocate | stack_logging_type_mapped_file_or_shared_mem; 313 // The target argument is the remote task from which data is being read, 314 // so pass mach_task_self() as the destination task receiving the allocation. 315 __syscall_logger(eventTypeFlags, (uintptr_t)mach_task_self(), (uintptr_t)*dataCnt, 0, *data, 0); 316 } 317 318 return (rv); 319} 320