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