xref: /minix3/crypto/external/bsd/heimdal/dist/lib/roken/test-mem.c (revision ebfedea0ce5bbe81e252ddf32d732e40fb633fae)
1 /*	$NetBSD: test-mem.c,v 1.1.1.1 2011/04/13 18:15:43 elric Exp $	*/
2 
3 /*
4  * Copyright (c) 1999 - 2004 Kungliga Tekniska Högskolan
5  * (Royal Institute of Technology, Stockholm, Sweden).
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the Institute nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 #include <config.h>
37 
38 #ifdef HAVE_SYS_MMAN_H
39 #include <sys/mman.h>
40 #endif
41 #include <stdio.h>
42 #include <string.h>
43 #include <err.h>
44 #include <krb5/roken.h>
45 
46 #include "test-mem.h"
47 
48 /* #undef HAVE_MMAP */
49 
50 struct {
51     void *start;
52     size_t size;
53     void *data_start;
54     size_t data_size;
55     enum rk_test_mem_type type;
56     int fd;
57 } map;
58 
59 #ifdef HAVE_SIGACTION
60 
61 struct sigaction sa, osa;
62 
63 #else
64 
65 void (* osigh)(int);
66 
67 #endif
68 
69 char *testname;
70 
71 static RETSIGTYPE
segv_handler(int sig)72 segv_handler(int sig)
73 {
74     int fd;
75     char msg[] = "SIGSEGV i current test: ";
76 
77     fd = open("/dev/stdout", O_WRONLY, 0600);
78     if (fd >= 0) {
79 	(void)write(fd, msg, sizeof(msg) - 1);
80 	(void)write(fd, testname, strlen(testname));
81 	(void)write(fd, "\n", 1);
82 	close(fd);
83     }
84     _exit(1);
85 }
86 
87 #define TESTREC()							\
88     if (testname)							\
89 	errx(1, "test %s run recursively on %s", name, testname);	\
90     testname = strdup(name);						\
91     if (testname == NULL)						\
92 	errx(1, "malloc");
93 
94 
95 ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL
rk_test_mem_alloc(enum rk_test_mem_type type,const char * name,void * buf,size_t size)96 rk_test_mem_alloc(enum rk_test_mem_type type, const char *name,
97 		  void *buf, size_t size)
98 {
99 #ifndef HAVE_MMAP
100     unsigned char *p;
101 
102     TESTREC();
103 
104     p = malloc(size + 2);
105     if (p == NULL)
106 	errx(1, "malloc");
107     map.type = type;
108     map.start = p;
109     map.size = size + 2;
110     p[0] = 0xff;
111     p[map.size-1] = 0xff;
112     map.data_start = p + 1;
113 #else
114     unsigned char *p;
115     int flags, ret, fd;
116     size_t pagesize = getpagesize();
117 
118     TESTREC();
119 
120     map.type = type;
121 
122 #ifdef MAP_ANON
123     flags = MAP_ANON;
124     fd = -1;
125 #else
126     flags = 0;
127     fd = open ("/dev/zero", O_RDONLY);
128     if(fd < 0)
129 	err (1, "open /dev/zero");
130 #endif
131     map.fd = fd;
132     flags |= MAP_PRIVATE;
133 
134     map.size = size + pagesize - (size % pagesize) + pagesize * 2;
135 
136     p = (unsigned char *)mmap(0, map.size, PROT_READ | PROT_WRITE,
137 			      flags, fd, 0);
138     if (p == (unsigned char *)MAP_FAILED)
139 	err (1, "mmap");
140 
141     map.start = p;
142 
143     ret = mprotect ((void *)p, pagesize, 0);
144     if (ret < 0)
145 	err (1, "mprotect");
146 
147     ret = mprotect (p + map.size - pagesize, pagesize, 0);
148     if (ret < 0)
149 	err (1, "mprotect");
150 
151     switch (type) {
152     case RK_TM_OVERRUN:
153 	map.data_start = p + map.size - pagesize - size;
154 	break;
155     case RK_TM_UNDERRUN:
156 	map.data_start = p + pagesize;
157 	break;
158     default:
159 	abort();
160     }
161 #endif
162 #ifdef HAVE_SIGACTION
163     sigemptyset (&sa.sa_mask);
164     sa.sa_flags = 0;
165 #ifdef SA_RESETHAND
166     sa.sa_flags |= SA_RESETHAND;
167 #endif
168     sa.sa_handler = segv_handler;
169     sigaction (SIGSEGV, &sa, &osa);
170 #else
171     osigh = signal(SIGSEGV, segv_handler);
172 #endif
173 
174     map.data_size = size;
175     if (buf)
176 	memcpy(map.data_start, buf, size);
177     return map.data_start;
178 }
179 
180 ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
rk_test_mem_free(const char * map_name)181 rk_test_mem_free(const char *map_name)
182 {
183 #ifndef HAVE_MMAP
184     unsigned char *p = map.start;
185 
186     if (testname == NULL)
187 	errx(1, "test_mem_free call on no free");
188 
189     if (p[0] != 0xff)
190 	errx(1, "%s: %s underrun %x\n", testname, map_name, p[0]);
191     if (p[map.size-1] != 0xff)
192 	errx(1, "%s: %s overrun %x\n", testname, map_name, p[map.size - 1]);
193     free(map.start);
194 #else
195     int ret;
196 
197     if (testname == NULL)
198 	errx(1, "test_mem_free call on no free");
199 
200     ret = munmap (map.start, map.size);
201     if (ret < 0)
202 	err (1, "munmap");
203     if (map.fd > 0)
204 	close(map.fd);
205 #endif
206     free(testname);
207     testname = NULL;
208 
209 #ifdef HAVE_SIGACTION
210     sigaction (SIGSEGV, &osa, NULL);
211 #else
212     signal (SIGSEGV, osigh);
213 #endif
214 }
215