1*0a6a1f1dSLionel Sambuc /* $NetBSD: check-common.c,v 1.1.1.2 2014/04/24 12:45:28 pettai Exp $ */
2ebfedea0SLionel Sambuc
3ebfedea0SLionel Sambuc /*
4ebfedea0SLionel Sambuc * Copyright (c) 1999 - 2006 Kungliga Tekniska Högskolan
5ebfedea0SLionel Sambuc * (Royal Institute of Technology, Stockholm, Sweden).
6ebfedea0SLionel Sambuc * All rights reserved.
7ebfedea0SLionel Sambuc *
8ebfedea0SLionel Sambuc * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
9ebfedea0SLionel Sambuc *
10ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without
11ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions
12ebfedea0SLionel Sambuc * are met:
13ebfedea0SLionel Sambuc *
14ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
15ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer.
16ebfedea0SLionel Sambuc *
17ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
18ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
19ebfedea0SLionel Sambuc * documentation and/or other materials provided with the distribution.
20ebfedea0SLionel Sambuc *
21ebfedea0SLionel Sambuc * 3. Neither the name of the Institute nor the names of its contributors
22ebfedea0SLionel Sambuc * may be used to endorse or promote products derived from this software
23ebfedea0SLionel Sambuc * without specific prior written permission.
24ebfedea0SLionel Sambuc *
25ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
26ebfedea0SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28ebfedea0SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
29ebfedea0SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30ebfedea0SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31ebfedea0SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33ebfedea0SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34ebfedea0SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35ebfedea0SLionel Sambuc * SUCH DAMAGE.
36ebfedea0SLionel Sambuc */
37ebfedea0SLionel Sambuc
38ebfedea0SLionel Sambuc #ifdef HAVE_CONFIG_H
39ebfedea0SLionel Sambuc #include <config.h>
40ebfedea0SLionel Sambuc #endif
41ebfedea0SLionel Sambuc #ifdef HAVE_SYS_MMAN_H
42ebfedea0SLionel Sambuc #include <sys/mman.h>
43ebfedea0SLionel Sambuc #endif
44ebfedea0SLionel Sambuc #include <stdio.h>
45ebfedea0SLionel Sambuc #include <string.h>
46ebfedea0SLionel Sambuc #include <err.h>
47ebfedea0SLionel Sambuc #include <krb5/roken.h>
48ebfedea0SLionel Sambuc
49ebfedea0SLionel Sambuc #include <krb5/asn1-common.h>
50ebfedea0SLionel Sambuc #include "check-common.h"
51ebfedea0SLionel Sambuc
52*0a6a1f1dSLionel Sambuc __RCSID("NetBSD");
53ebfedea0SLionel Sambuc
54ebfedea0SLionel Sambuc struct map_page {
55ebfedea0SLionel Sambuc void *start;
56ebfedea0SLionel Sambuc size_t size;
57ebfedea0SLionel Sambuc void *data_start;
58ebfedea0SLionel Sambuc size_t data_size;
59ebfedea0SLionel Sambuc enum map_type type;
60ebfedea0SLionel Sambuc };
61ebfedea0SLionel Sambuc
62ebfedea0SLionel Sambuc /* #undef HAVE_MMAP */
63ebfedea0SLionel Sambuc
64ebfedea0SLionel Sambuc void *
map_alloc(enum map_type type,const void * buf,size_t size,struct map_page ** map)65ebfedea0SLionel Sambuc map_alloc(enum map_type type, const void *buf,
66ebfedea0SLionel Sambuc size_t size, struct map_page **map)
67ebfedea0SLionel Sambuc {
68ebfedea0SLionel Sambuc #ifndef HAVE_MMAP
69ebfedea0SLionel Sambuc unsigned char *p;
70ebfedea0SLionel Sambuc size_t len = size + sizeof(long) * 2;
71ebfedea0SLionel Sambuc int i;
72ebfedea0SLionel Sambuc
73ebfedea0SLionel Sambuc *map = ecalloc(1, sizeof(**map));
74ebfedea0SLionel Sambuc
75ebfedea0SLionel Sambuc p = emalloc(len);
76ebfedea0SLionel Sambuc (*map)->type = type;
77ebfedea0SLionel Sambuc (*map)->start = p;
78ebfedea0SLionel Sambuc (*map)->size = len;
79ebfedea0SLionel Sambuc (*map)->data_start = p + sizeof(long);
80ebfedea0SLionel Sambuc for (i = sizeof(long); i > 0; i--)
81ebfedea0SLionel Sambuc p[sizeof(long) - i] = 0xff - i;
82ebfedea0SLionel Sambuc for (i = sizeof(long); i > 0; i--)
83ebfedea0SLionel Sambuc p[len - i] = 0xff - i;
84ebfedea0SLionel Sambuc #else
85ebfedea0SLionel Sambuc unsigned char *p;
86ebfedea0SLionel Sambuc int flags, ret, fd;
87ebfedea0SLionel Sambuc size_t pagesize = getpagesize();
88ebfedea0SLionel Sambuc
89ebfedea0SLionel Sambuc *map = ecalloc(1, sizeof(**map));
90ebfedea0SLionel Sambuc
91ebfedea0SLionel Sambuc (*map)->type = type;
92ebfedea0SLionel Sambuc
93ebfedea0SLionel Sambuc #ifdef MAP_ANON
94ebfedea0SLionel Sambuc flags = MAP_ANON;
95ebfedea0SLionel Sambuc fd = -1;
96ebfedea0SLionel Sambuc #else
97ebfedea0SLionel Sambuc flags = 0;
98ebfedea0SLionel Sambuc fd = open ("/dev/zero", O_RDONLY);
99ebfedea0SLionel Sambuc if(fd < 0)
100ebfedea0SLionel Sambuc err (1, "open /dev/zero");
101ebfedea0SLionel Sambuc #endif
102ebfedea0SLionel Sambuc flags |= MAP_PRIVATE;
103ebfedea0SLionel Sambuc
104ebfedea0SLionel Sambuc (*map)->size = size + pagesize - (size % pagesize) + pagesize * 2;
105ebfedea0SLionel Sambuc
106ebfedea0SLionel Sambuc p = (unsigned char *)mmap(0, (*map)->size, PROT_READ | PROT_WRITE,
107ebfedea0SLionel Sambuc flags, fd, 0);
108ebfedea0SLionel Sambuc if (p == (unsigned char *)MAP_FAILED)
109ebfedea0SLionel Sambuc err (1, "mmap");
110ebfedea0SLionel Sambuc
111ebfedea0SLionel Sambuc (*map)->start = p;
112ebfedea0SLionel Sambuc
113ebfedea0SLionel Sambuc ret = mprotect (p, pagesize, 0);
114ebfedea0SLionel Sambuc if (ret < 0)
115ebfedea0SLionel Sambuc err (1, "mprotect");
116ebfedea0SLionel Sambuc
117ebfedea0SLionel Sambuc ret = mprotect (p + (*map)->size - pagesize, pagesize, 0);
118ebfedea0SLionel Sambuc if (ret < 0)
119ebfedea0SLionel Sambuc err (1, "mprotect");
120ebfedea0SLionel Sambuc
121ebfedea0SLionel Sambuc switch (type) {
122ebfedea0SLionel Sambuc case OVERRUN:
123ebfedea0SLionel Sambuc (*map)->data_start = p + (*map)->size - pagesize - size;
124ebfedea0SLionel Sambuc break;
125ebfedea0SLionel Sambuc case UNDERRUN:
126ebfedea0SLionel Sambuc (*map)->data_start = p + pagesize;
127ebfedea0SLionel Sambuc break;
128ebfedea0SLionel Sambuc default:
129ebfedea0SLionel Sambuc abort();
130ebfedea0SLionel Sambuc }
131ebfedea0SLionel Sambuc #endif
132ebfedea0SLionel Sambuc (*map)->data_size = size;
133ebfedea0SLionel Sambuc if (buf)
134ebfedea0SLionel Sambuc memcpy((*map)->data_start, buf, size);
135ebfedea0SLionel Sambuc return (*map)->data_start;
136ebfedea0SLionel Sambuc }
137ebfedea0SLionel Sambuc
138ebfedea0SLionel Sambuc void
map_free(struct map_page * map,const char * test_name,const char * map_name)139ebfedea0SLionel Sambuc map_free(struct map_page *map, const char *test_name, const char *map_name)
140ebfedea0SLionel Sambuc {
141ebfedea0SLionel Sambuc #ifndef HAVE_MMAP
142ebfedea0SLionel Sambuc unsigned char *p = map->start;
143ebfedea0SLionel Sambuc int i;
144ebfedea0SLionel Sambuc
145ebfedea0SLionel Sambuc for (i = sizeof(long); i > 0; i--)
146ebfedea0SLionel Sambuc if (p[sizeof(long) - i] != 0xff - i)
147ebfedea0SLionel Sambuc errx(1, "%s: %s underrun %d\n", test_name, map_name, i);
148ebfedea0SLionel Sambuc for (i = sizeof(long); i > 0; i--)
149ebfedea0SLionel Sambuc if (p[map->size - i] != 0xff - i)
150ebfedea0SLionel Sambuc errx(1, "%s: %s overrun %lu\n", test_name, map_name,
151ebfedea0SLionel Sambuc (unsigned long)map->size - i);
152ebfedea0SLionel Sambuc free(map->start);
153ebfedea0SLionel Sambuc #else
154ebfedea0SLionel Sambuc int ret;
155ebfedea0SLionel Sambuc
156ebfedea0SLionel Sambuc ret = munmap (map->start, map->size);
157ebfedea0SLionel Sambuc if (ret < 0)
158ebfedea0SLionel Sambuc err (1, "munmap");
159ebfedea0SLionel Sambuc #endif
160ebfedea0SLionel Sambuc free(map);
161ebfedea0SLionel Sambuc }
162ebfedea0SLionel Sambuc
163ebfedea0SLionel Sambuc static void
print_bytes(unsigned const char * buf,size_t len)164ebfedea0SLionel Sambuc print_bytes (unsigned const char *buf, size_t len)
165ebfedea0SLionel Sambuc {
166ebfedea0SLionel Sambuc int i;
167ebfedea0SLionel Sambuc
168ebfedea0SLionel Sambuc for (i = 0; i < len; ++i)
169ebfedea0SLionel Sambuc printf ("%02x ", buf[i]);
170ebfedea0SLionel Sambuc }
171ebfedea0SLionel Sambuc
172ebfedea0SLionel Sambuc #ifndef MAP_FAILED
173ebfedea0SLionel Sambuc #define MAP_FAILED (-1)
174ebfedea0SLionel Sambuc #endif
175ebfedea0SLionel Sambuc
176ebfedea0SLionel Sambuc static char *current_test = "<uninit>";
177ebfedea0SLionel Sambuc static char *current_state = "<uninit>";
178ebfedea0SLionel Sambuc
179ebfedea0SLionel Sambuc static RETSIGTYPE
segv_handler(int sig)180ebfedea0SLionel Sambuc segv_handler(int sig)
181ebfedea0SLionel Sambuc {
182ebfedea0SLionel Sambuc int fd;
183ebfedea0SLionel Sambuc char msg[] = "SIGSEGV i current test: ";
184ebfedea0SLionel Sambuc
185ebfedea0SLionel Sambuc fd = open("/dev/stdout", O_WRONLY, 0600);
186ebfedea0SLionel Sambuc if (fd >= 0) {
187ebfedea0SLionel Sambuc write(fd, msg, sizeof(msg));
188ebfedea0SLionel Sambuc write(fd, current_test, strlen(current_test));
189ebfedea0SLionel Sambuc write(fd, " ", 1);
190ebfedea0SLionel Sambuc write(fd, current_state, strlen(current_state));
191ebfedea0SLionel Sambuc write(fd, "\n", 1);
192ebfedea0SLionel Sambuc close(fd);
193ebfedea0SLionel Sambuc }
194ebfedea0SLionel Sambuc _exit(1);
195ebfedea0SLionel Sambuc }
196ebfedea0SLionel Sambuc
197ebfedea0SLionel Sambuc int
generic_test(const struct test_case * tests,unsigned ntests,size_t data_size,int (ASN1CALL * encode)(unsigned char *,size_t,void *,size_t *),int (ASN1CALL * length)(void *),int (ASN1CALL * decode)(unsigned char *,size_t,void *,size_t *),int (ASN1CALL * free_data)(void *),int (* cmp)(void * a,void * b),int (ASN1CALL * copy)(const void * from,void * to))198ebfedea0SLionel Sambuc generic_test (const struct test_case *tests,
199ebfedea0SLionel Sambuc unsigned ntests,
200ebfedea0SLionel Sambuc size_t data_size,
201ebfedea0SLionel Sambuc int (ASN1CALL *encode)(unsigned char *, size_t, void *, size_t *),
202ebfedea0SLionel Sambuc int (ASN1CALL *length)(void *),
203ebfedea0SLionel Sambuc int (ASN1CALL *decode)(unsigned char *, size_t, void *, size_t *),
204ebfedea0SLionel Sambuc int (ASN1CALL *free_data)(void *),
205ebfedea0SLionel Sambuc int (*cmp)(void *a, void *b),
206ebfedea0SLionel Sambuc int (ASN1CALL *copy)(const void *from, void *to))
207ebfedea0SLionel Sambuc {
208ebfedea0SLionel Sambuc unsigned char *buf, *buf2;
209ebfedea0SLionel Sambuc int i;
210ebfedea0SLionel Sambuc int failures = 0;
211ebfedea0SLionel Sambuc void *data;
212ebfedea0SLionel Sambuc struct map_page *data_map, *buf_map, *buf2_map;
213ebfedea0SLionel Sambuc
214ebfedea0SLionel Sambuc #ifdef HAVE_SIGACTION
215ebfedea0SLionel Sambuc struct sigaction sa, osa;
216ebfedea0SLionel Sambuc #endif
217ebfedea0SLionel Sambuc
218ebfedea0SLionel Sambuc for (i = 0; i < ntests; ++i) {
219ebfedea0SLionel Sambuc int ret;
220ebfedea0SLionel Sambuc size_t sz, consumed_sz, length_sz, buf_sz;
221ebfedea0SLionel Sambuc void *to = NULL;
222ebfedea0SLionel Sambuc
223ebfedea0SLionel Sambuc current_test = tests[i].name;
224ebfedea0SLionel Sambuc
225ebfedea0SLionel Sambuc current_state = "init";
226ebfedea0SLionel Sambuc
227ebfedea0SLionel Sambuc #ifdef HAVE_SIGACTION
228ebfedea0SLionel Sambuc sigemptyset (&sa.sa_mask);
229ebfedea0SLionel Sambuc sa.sa_flags = 0;
230ebfedea0SLionel Sambuc #ifdef SA_RESETHAND
231ebfedea0SLionel Sambuc sa.sa_flags |= SA_RESETHAND;
232ebfedea0SLionel Sambuc #endif
233ebfedea0SLionel Sambuc sa.sa_handler = segv_handler;
234ebfedea0SLionel Sambuc sigaction (SIGSEGV, &sa, &osa);
235ebfedea0SLionel Sambuc #endif
236ebfedea0SLionel Sambuc
237ebfedea0SLionel Sambuc data = map_alloc(OVERRUN, NULL, data_size, &data_map);
238ebfedea0SLionel Sambuc
239ebfedea0SLionel Sambuc buf_sz = tests[i].byte_len;
240ebfedea0SLionel Sambuc buf = map_alloc(UNDERRUN, NULL, buf_sz, &buf_map);
241ebfedea0SLionel Sambuc
242ebfedea0SLionel Sambuc current_state = "encode";
243ebfedea0SLionel Sambuc ret = (*encode) (buf + buf_sz - 1, buf_sz,
244ebfedea0SLionel Sambuc tests[i].val, &sz);
245ebfedea0SLionel Sambuc if (ret != 0) {
246ebfedea0SLionel Sambuc printf ("encoding of %s failed %d\n", tests[i].name, ret);
247ebfedea0SLionel Sambuc ++failures;
248ebfedea0SLionel Sambuc continue;
249ebfedea0SLionel Sambuc }
250ebfedea0SLionel Sambuc if (sz != tests[i].byte_len) {
251ebfedea0SLionel Sambuc printf ("encoding of %s has wrong len (%lu != %lu)\n",
252ebfedea0SLionel Sambuc tests[i].name,
253ebfedea0SLionel Sambuc (unsigned long)sz, (unsigned long)tests[i].byte_len);
254ebfedea0SLionel Sambuc ++failures;
255ebfedea0SLionel Sambuc continue;
256ebfedea0SLionel Sambuc }
257ebfedea0SLionel Sambuc
258ebfedea0SLionel Sambuc current_state = "length";
259ebfedea0SLionel Sambuc length_sz = (*length) (tests[i].val);
260ebfedea0SLionel Sambuc if (sz != length_sz) {
261ebfedea0SLionel Sambuc printf ("length for %s is bad (%lu != %lu)\n",
262ebfedea0SLionel Sambuc tests[i].name, (unsigned long)length_sz, (unsigned long)sz);
263ebfedea0SLionel Sambuc ++failures;
264ebfedea0SLionel Sambuc continue;
265ebfedea0SLionel Sambuc }
266ebfedea0SLionel Sambuc
267ebfedea0SLionel Sambuc current_state = "memcmp";
268ebfedea0SLionel Sambuc if (memcmp (buf, tests[i].bytes, tests[i].byte_len) != 0) {
269ebfedea0SLionel Sambuc printf ("encoding of %s has bad bytes:\n"
270ebfedea0SLionel Sambuc "correct: ", tests[i].name);
271ebfedea0SLionel Sambuc print_bytes ((unsigned char *)tests[i].bytes, tests[i].byte_len);
272ebfedea0SLionel Sambuc printf ("\nactual: ");
273ebfedea0SLionel Sambuc print_bytes (buf, sz);
274ebfedea0SLionel Sambuc printf ("\n");
275ebfedea0SLionel Sambuc #if 0
276ebfedea0SLionel Sambuc rk_dumpdata("correct", tests[i].bytes, tests[i].byte_len);
277ebfedea0SLionel Sambuc rk_dumpdata("actual", buf, sz);
278ebfedea0SLionel Sambuc exit (1);
279ebfedea0SLionel Sambuc #endif
280ebfedea0SLionel Sambuc ++failures;
281ebfedea0SLionel Sambuc continue;
282ebfedea0SLionel Sambuc }
283ebfedea0SLionel Sambuc
284ebfedea0SLionel Sambuc buf2 = map_alloc(OVERRUN, buf, sz, &buf2_map);
285ebfedea0SLionel Sambuc
286ebfedea0SLionel Sambuc current_state = "decode";
287ebfedea0SLionel Sambuc ret = (*decode) (buf2, sz, data, &consumed_sz);
288ebfedea0SLionel Sambuc if (ret != 0) {
289ebfedea0SLionel Sambuc printf ("decoding of %s failed %d\n", tests[i].name, ret);
290ebfedea0SLionel Sambuc ++failures;
291ebfedea0SLionel Sambuc continue;
292ebfedea0SLionel Sambuc }
293ebfedea0SLionel Sambuc if (sz != consumed_sz) {
294ebfedea0SLionel Sambuc printf ("different length decoding %s (%ld != %ld)\n",
295ebfedea0SLionel Sambuc tests[i].name,
296ebfedea0SLionel Sambuc (unsigned long)sz, (unsigned long)consumed_sz);
297ebfedea0SLionel Sambuc ++failures;
298ebfedea0SLionel Sambuc continue;
299ebfedea0SLionel Sambuc }
300ebfedea0SLionel Sambuc current_state = "cmp";
301ebfedea0SLionel Sambuc if ((*cmp)(data, tests[i].val) != 0) {
302ebfedea0SLionel Sambuc printf ("%s: comparison failed\n", tests[i].name);
303ebfedea0SLionel Sambuc ++failures;
304ebfedea0SLionel Sambuc continue;
305ebfedea0SLionel Sambuc }
306ebfedea0SLionel Sambuc
307ebfedea0SLionel Sambuc current_state = "copy";
308ebfedea0SLionel Sambuc if (copy) {
309ebfedea0SLionel Sambuc to = emalloc(data_size);
310ebfedea0SLionel Sambuc ret = (*copy)(data, to);
311ebfedea0SLionel Sambuc if (ret != 0) {
312ebfedea0SLionel Sambuc printf ("copy of %s failed %d\n", tests[i].name, ret);
313ebfedea0SLionel Sambuc ++failures;
314ebfedea0SLionel Sambuc continue;
315ebfedea0SLionel Sambuc }
316ebfedea0SLionel Sambuc
317ebfedea0SLionel Sambuc current_state = "cmp-copy";
318ebfedea0SLionel Sambuc if ((*cmp)(data, to) != 0) {
319ebfedea0SLionel Sambuc printf ("%s: copy comparison failed\n", tests[i].name);
320ebfedea0SLionel Sambuc ++failures;
321ebfedea0SLionel Sambuc continue;
322ebfedea0SLionel Sambuc }
323ebfedea0SLionel Sambuc }
324ebfedea0SLionel Sambuc
325ebfedea0SLionel Sambuc current_state = "free";
326ebfedea0SLionel Sambuc if (free_data) {
327ebfedea0SLionel Sambuc (*free_data)(data);
328ebfedea0SLionel Sambuc if (to) {
329ebfedea0SLionel Sambuc (*free_data)(to);
330ebfedea0SLionel Sambuc free(to);
331ebfedea0SLionel Sambuc }
332ebfedea0SLionel Sambuc }
333ebfedea0SLionel Sambuc
334ebfedea0SLionel Sambuc current_state = "free";
335ebfedea0SLionel Sambuc map_free(buf_map, tests[i].name, "encode");
336ebfedea0SLionel Sambuc map_free(buf2_map, tests[i].name, "decode");
337ebfedea0SLionel Sambuc map_free(data_map, tests[i].name, "data");
338ebfedea0SLionel Sambuc
339ebfedea0SLionel Sambuc #ifdef HAVE_SIGACTION
340ebfedea0SLionel Sambuc sigaction (SIGSEGV, &osa, NULL);
341ebfedea0SLionel Sambuc #endif
342ebfedea0SLionel Sambuc }
343ebfedea0SLionel Sambuc current_state = "done";
344ebfedea0SLionel Sambuc return failures;
345ebfedea0SLionel Sambuc }
346ebfedea0SLionel Sambuc
347ebfedea0SLionel Sambuc /*
348ebfedea0SLionel Sambuc * check for failures
349ebfedea0SLionel Sambuc *
350ebfedea0SLionel Sambuc * a test size (byte_len) of -1 means that the test tries to trigger a
351ebfedea0SLionel Sambuc * integer overflow (and later a malloc of to little memory), just
352ebfedea0SLionel Sambuc * allocate some memory and hope that is enough for that test.
353ebfedea0SLionel Sambuc */
354ebfedea0SLionel Sambuc
355ebfedea0SLionel Sambuc int
generic_decode_fail(const struct test_case * tests,unsigned ntests,size_t data_size,int (ASN1CALL * decode)(unsigned char *,size_t,void *,size_t *))356ebfedea0SLionel Sambuc generic_decode_fail (const struct test_case *tests,
357ebfedea0SLionel Sambuc unsigned ntests,
358ebfedea0SLionel Sambuc size_t data_size,
359ebfedea0SLionel Sambuc int (ASN1CALL *decode)(unsigned char *, size_t, void *, size_t *))
360ebfedea0SLionel Sambuc {
361ebfedea0SLionel Sambuc unsigned char *buf;
362ebfedea0SLionel Sambuc int i;
363ebfedea0SLionel Sambuc int failures = 0;
364ebfedea0SLionel Sambuc void *data;
365ebfedea0SLionel Sambuc struct map_page *data_map, *buf_map;
366ebfedea0SLionel Sambuc
367ebfedea0SLionel Sambuc #ifdef HAVE_SIGACTION
368ebfedea0SLionel Sambuc struct sigaction sa, osa;
369ebfedea0SLionel Sambuc #endif
370ebfedea0SLionel Sambuc
371ebfedea0SLionel Sambuc for (i = 0; i < ntests; ++i) {
372ebfedea0SLionel Sambuc int ret;
373ebfedea0SLionel Sambuc size_t sz;
374ebfedea0SLionel Sambuc const void *bytes;
375ebfedea0SLionel Sambuc
376ebfedea0SLionel Sambuc current_test = tests[i].name;
377ebfedea0SLionel Sambuc
378ebfedea0SLionel Sambuc current_state = "init";
379ebfedea0SLionel Sambuc
380ebfedea0SLionel Sambuc #ifdef HAVE_SIGACTION
381ebfedea0SLionel Sambuc sigemptyset (&sa.sa_mask);
382ebfedea0SLionel Sambuc sa.sa_flags = 0;
383ebfedea0SLionel Sambuc #ifdef SA_RESETHAND
384ebfedea0SLionel Sambuc sa.sa_flags |= SA_RESETHAND;
385ebfedea0SLionel Sambuc #endif
386ebfedea0SLionel Sambuc sa.sa_handler = segv_handler;
387ebfedea0SLionel Sambuc sigaction (SIGSEGV, &sa, &osa);
388ebfedea0SLionel Sambuc #endif
389ebfedea0SLionel Sambuc
390ebfedea0SLionel Sambuc data = map_alloc(OVERRUN, NULL, data_size, &data_map);
391ebfedea0SLionel Sambuc
392ebfedea0SLionel Sambuc if (tests[i].byte_len < 0xffffff && tests[i].byte_len >= 0) {
393ebfedea0SLionel Sambuc sz = tests[i].byte_len;
394ebfedea0SLionel Sambuc bytes = tests[i].bytes;
395ebfedea0SLionel Sambuc } else {
396ebfedea0SLionel Sambuc sz = 4096;
397ebfedea0SLionel Sambuc bytes = NULL;
398ebfedea0SLionel Sambuc }
399ebfedea0SLionel Sambuc
400ebfedea0SLionel Sambuc buf = map_alloc(OVERRUN, bytes, sz, &buf_map);
401ebfedea0SLionel Sambuc
402ebfedea0SLionel Sambuc if (tests[i].byte_len == -1)
403ebfedea0SLionel Sambuc memset(buf, 0, sz);
404ebfedea0SLionel Sambuc
405ebfedea0SLionel Sambuc current_state = "decode";
406ebfedea0SLionel Sambuc ret = (*decode) (buf, tests[i].byte_len, data, &sz);
407ebfedea0SLionel Sambuc if (ret == 0) {
408ebfedea0SLionel Sambuc printf ("sucessfully decoded %s\n", tests[i].name);
409ebfedea0SLionel Sambuc ++failures;
410ebfedea0SLionel Sambuc continue;
411ebfedea0SLionel Sambuc }
412ebfedea0SLionel Sambuc
413ebfedea0SLionel Sambuc current_state = "free";
414ebfedea0SLionel Sambuc if (buf)
415ebfedea0SLionel Sambuc map_free(buf_map, tests[i].name, "encode");
416ebfedea0SLionel Sambuc map_free(data_map, tests[i].name, "data");
417ebfedea0SLionel Sambuc
418ebfedea0SLionel Sambuc #ifdef HAVE_SIGACTION
419ebfedea0SLionel Sambuc sigaction (SIGSEGV, &osa, NULL);
420ebfedea0SLionel Sambuc #endif
421ebfedea0SLionel Sambuc }
422ebfedea0SLionel Sambuc current_state = "done";
423ebfedea0SLionel Sambuc return failures;
424ebfedea0SLionel Sambuc }
425