1 /* 2 * Copyright (C) 2005, 2006, 2007, 2010 Apple Inc. All rights reserved. 3 * (C) 2007 Graham Dennis (graham.dennis (at) gmail.com) 4 * (C) 2007 Eric Seidel <eric (at) webkit.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 16 * its contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #import "config.h" 32 #import "CheckedMalloc.h" 33 34 #import <mach/mach_init.h> 35 #import <mach/mach_vm.h> 36 #import <mach/vm_region.h> 37 #import <malloc/malloc.h> 38 39 static void* (*savedMalloc)(malloc_zone_t*, size_t); 40 static void* (*savedRealloc)(malloc_zone_t*, void*, size_t); 41 42 static void* checkedMalloc(malloc_zone_t* zone, size_t size) 43 { 44 if (size >= 0x10000000) 45 return 0; 46 return savedMalloc(zone, size); 47 } 48 49 static void* checkedRealloc(malloc_zone_t* zone, void* ptr, size_t size) 50 { 51 if (size >= 0x10000000) 52 return 0; 53 return savedRealloc(zone, ptr, size); 54 } 55 56 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 57 static vm_prot_t protectionOfRegion(mach_vm_address_t address) 58 { 59 mach_vm_size_t regionSize = 0; 60 vm_region_basic_info_64 regionInfo; 61 mach_msg_type_number_t regionInfoCount = VM_REGION_BASIC_INFO_COUNT_64; 62 mach_port_t objectName; 63 if (mach_vm_region(mach_task_self(), &address, ®ionSize, VM_REGION_BASIC_INFO_64, (vm_region_info_t)®ionInfo, ®ionInfoCount, &objectName)) 64 CRASH(); 65 return regionInfo.protection; 66 } 67 #endif 68 69 void makeLargeMallocFailSilently() 70 { 71 malloc_zone_t* zone = malloc_default_zone(); 72 73 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 74 mach_vm_address_t pageStart = reinterpret_cast<vm_address_t>(zone) & static_cast<vm_size_t>(~(getpagesize() - 1)); 75 vm_prot_t initialProtection = protectionOfRegion(pageStart); 76 77 vm_size_t len = reinterpret_cast<vm_address_t>(zone) - pageStart + sizeof(malloc_zone_t); 78 if (mach_vm_protect(mach_task_self(), pageStart, len, 0, initialProtection | VM_PROT_WRITE)) 79 CRASH(); 80 #endif 81 82 savedMalloc = zone->malloc; 83 savedRealloc = zone->realloc; 84 zone->malloc = checkedMalloc; 85 zone->realloc = checkedRealloc; 86 87 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 88 if (mach_vm_protect(mach_task_self(), pageStart, len, 0, initialProtection)) 89 CRASH(); 90 #endif 91 } 92