1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
/* Test that the handler is called, with the right fault address. */
#include "sigsegv.h"
#ifdef _WIN32
#define HAVE_WIN32_VM
#else
#include "config.h"
#endif
#if defined(HAVE_SIGSEGV_RECOVERY) && (((defined(HAVE_MMAP_ANONYMOUS) || defined(HAVE_MMAP_ANON) || defined(HAVE_MMAP_DEVZERO) || defined(HAVE_MMAP_DEVZERO_SUN4_29)) && defined(HAVE_WORKING_MPROTECT)) || defined(HAVE_MACH_VM) || defined(HAVE_WIN32_VM))
/* First some auxiliary stuff for using mmap & friends. */
#if defined(HAVE_MACH_VM)
#include <sys/resource.h>
#include <mach/mach_interface.h>
#ifdef NeXT
#include <mach/mach_init.h>
#endif
#ifdef __osf__
#include <mach_init.h>
#endif
#include <mach/mach_traps.h>
#include <mach/machine/vm_param.h>
#define PROT_NONE 0
#define PROT_READ VM_PROT_READ
#define PROT_WRITE VM_PROT_WRITE
#define PROT_EXEC VM_PROT_EXECUTE
#define PROT_READ_WRITE (PROT_READ|PROT_WRITE)
static int mmap_zeromap (void* map_addr, vm_size_t map_len)
{
if (vm_allocate(task_self(), (vm_address_t*) &map_addr, map_len, 0) == KERN_SUCCESS)
return 0;
else
return -1;
}
int munmap (vm_address_t addr, vm_size_t len)
{
if (vm_deallocate(task_self(),addr,len) == KERN_SUCCESS)
return 0;
else
return -1;
}
int mprotect (vm_address_t addr, vm_size_t len, int prot)
{
if (vm_protect(task_self(),addr,len,0,prot) == KERN_SUCCESS)
return 0;
else
return -1;
}
#endif
#if defined(HAVE_WIN32_VM)
#define WIN32_LEAN_AND_MEAN /* avoid including junk */
#include <windows.h>
#include <winerror.h>
#define PROT_NONE PAGE_NOACCESS
#define PROT_READ PAGE_READONLY
#define PROT_READ_WRITE PAGE_READWRITE
static int mmap_zeromap (void* map_addr, unsigned long map_len)
{
if (VirtualAlloc(map_addr,map_len,MEM_COMMIT,PAGE_READWRITE))
return 0;
else
return -1;
}
int munmap (void* addr, unsigned long len)
{
if (VirtualFree(addr,len,MEM_DECOMMIT))
return 0;
else
return -1;
}
int mprotect (void* addr, unsigned long len, int prot)
{
DWORD oldprot;
if (VirtualProtect(addr,len,prot,&oldprot))
return 0;
else
return -1;
}
#endif
#if defined(HAVE_MMAP_ANONYMOUS) || defined(HAVE_MMAP_ANON) || defined(HAVE_MMAP_DEVZERO) || defined(HAVE_MMAP_DEVZERO_SUN4_29)
#include <sys/types.h>
#include <sys/mman.h>
#ifndef PROT_NONE
#define PROT_NONE 0
#endif
#define PROT_READ_WRITE (PROT_READ|PROT_WRITE)
#ifdef HAVE_MMAP_ANONYMOUS
#define zero_fd -1
#define map_flags MAP_ANONYMOUS | MAP_PRIVATE
#else
#ifdef HAVE_MMAP_ANON
#define zero_fd -1
#define map_flags MAP_ANON | MAP_PRIVATE
#else
#include <fcntl.h>
#ifdef OPEN_NEEDS_SYS_FILE_H
#include <sys/file.h>
#endif
static int zero_fd;
#ifdef MAP_FILE
#define map_flags MAP_FILE | MAP_PRIVATE
#else
#define map_flags MAP_PRIVATE
#endif
#endif
#endif
static int mmap_zeromap (void* map_addr, unsigned long map_len)
{
if ((void*) mmap(map_addr,map_len, PROT_READ_WRITE, map_flags | MAP_FIXED, zero_fd, 0) == (void*)(-1))
return -1;
else
return 0;
}
#endif
/* Now the test program. */
int handler_called = 0;
int handler (void* fault_address, int serious)
{
handler_called++;
if (fault_address != (void*)0x12340678) abort();
if (mprotect((void*)((unsigned long)fault_address & -0x4000),0x4000,PROT_READ_WRITE) == 0) return 1;
return 0;
}
void crasher (unsigned long p)
{
*(int*)(p + 0x678) = 42;
}
int main ()
{
unsigned long page = 0x12340000;
#if (defined(HAVE_MMAP_DEVZERO) || defined(HAVE_MMAP_DEVZERO_SUN4_29)) && !defined(HAVE_MMAP_ANON)
zero_fd = open("/dev/zero",O_RDONLY,0644);
#endif
#ifdef HAVE_WIN32_VM
VirtualAlloc((void*)(page & -0x10000),0x10000,MEM_RESERVE,PAGE_NOACCESS);
#endif
mmap_zeromap((void*)page,0x4000);
mprotect((void*)page,0x4000,PROT_READ);
sigsegv_install_handler(&handler);
crasher(page);
crasher(page);
if (handler_called != 1) exit(1);
return 0;
}
#else
int main ()
{
return 0;
}
#endif
|