1 /* $NetBSD: check-common.c,v 1.1.1.2 2014/04/24 12:45:28 pettai Exp $ */
4 * Copyright (c) 1999 - 2006 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the Institute nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 #ifdef HAVE_SYS_MMAN_H
47 #include <krb5/roken.h>
49 #include <krb5/asn1-common.h>
50 #include "check-common.h"
62 /* #undef HAVE_MMAP */
65 map_alloc(enum map_type type
, const void *buf
,
66 size_t size
, struct map_page
**map
)
70 size_t len
= size
+ sizeof(long) * 2;
73 *map
= ecalloc(1, sizeof(**map
));
79 (*map
)->data_start
= p
+ sizeof(long);
80 for (i
= sizeof(long); i
> 0; i
--)
81 p
[sizeof(long) - i
] = 0xff - i
;
82 for (i
= sizeof(long); i
> 0; i
--)
83 p
[len
- i
] = 0xff - i
;
87 size_t pagesize
= getpagesize();
89 *map
= ecalloc(1, sizeof(**map
));
98 fd
= open ("/dev/zero", O_RDONLY
);
100 err (1, "open /dev/zero");
102 flags
|= MAP_PRIVATE
;
104 (*map
)->size
= size
+ pagesize
- (size
% pagesize
) + pagesize
* 2;
106 p
= (unsigned char *)mmap(0, (*map
)->size
, PROT_READ
| PROT_WRITE
,
108 if (p
== (unsigned char *)MAP_FAILED
)
113 ret
= mprotect (p
, pagesize
, 0);
117 ret
= mprotect (p
+ (*map
)->size
- pagesize
, pagesize
, 0);
123 (*map
)->data_start
= p
+ (*map
)->size
- pagesize
- size
;
126 (*map
)->data_start
= p
+ pagesize
;
132 (*map
)->data_size
= size
;
134 memcpy((*map
)->data_start
, buf
, size
);
135 return (*map
)->data_start
;
139 map_free(struct map_page
*map
, const char *test_name
, const char *map_name
)
142 unsigned char *p
= map
->start
;
145 for (i
= sizeof(long); i
> 0; i
--)
146 if (p
[sizeof(long) - i
] != 0xff - i
)
147 errx(1, "%s: %s underrun %d\n", test_name
, map_name
, i
);
148 for (i
= sizeof(long); i
> 0; i
--)
149 if (p
[map
->size
- i
] != 0xff - i
)
150 errx(1, "%s: %s overrun %lu\n", test_name
, map_name
,
151 (unsigned long)map
->size
- i
);
156 ret
= munmap (map
->start
, map
->size
);
164 print_bytes (unsigned const char *buf
, size_t len
)
168 for (i
= 0; i
< len
; ++i
)
169 printf ("%02x ", buf
[i
]);
173 #define MAP_FAILED (-1)
176 static char *current_test
= "<uninit>";
177 static char *current_state
= "<uninit>";
180 segv_handler(int sig
)
183 char msg
[] = "SIGSEGV i current test: ";
185 fd
= open("/dev/stdout", O_WRONLY
, 0600);
187 write(fd
, msg
, sizeof(msg
));
188 write(fd
, current_test
, strlen(current_test
));
190 write(fd
, current_state
, strlen(current_state
));
198 generic_test (const struct test_case
*tests
,
201 int (ASN1CALL
*encode
)(unsigned char *, size_t, void *, size_t *),
202 int (ASN1CALL
*length
)(void *),
203 int (ASN1CALL
*decode
)(unsigned char *, size_t, void *, size_t *),
204 int (ASN1CALL
*free_data
)(void *),
205 int (*cmp
)(void *a
, void *b
),
206 int (ASN1CALL
*copy
)(const void *from
, void *to
))
208 unsigned char *buf
, *buf2
;
212 struct map_page
*data_map
, *buf_map
, *buf2_map
;
214 #ifdef HAVE_SIGACTION
215 struct sigaction sa
, osa
;
218 for (i
= 0; i
< ntests
; ++i
) {
220 size_t sz
, consumed_sz
, length_sz
, buf_sz
;
223 current_test
= tests
[i
].name
;
225 current_state
= "init";
227 #ifdef HAVE_SIGACTION
228 sigemptyset (&sa
.sa_mask
);
231 sa
.sa_flags
|= SA_RESETHAND
;
233 sa
.sa_handler
= segv_handler
;
234 sigaction (SIGSEGV
, &sa
, &osa
);
237 data
= map_alloc(OVERRUN
, NULL
, data_size
, &data_map
);
239 buf_sz
= tests
[i
].byte_len
;
240 buf
= map_alloc(UNDERRUN
, NULL
, buf_sz
, &buf_map
);
242 current_state
= "encode";
243 ret
= (*encode
) (buf
+ buf_sz
- 1, buf_sz
,
246 printf ("encoding of %s failed %d\n", tests
[i
].name
, ret
);
250 if (sz
!= tests
[i
].byte_len
) {
251 printf ("encoding of %s has wrong len (%lu != %lu)\n",
253 (unsigned long)sz
, (unsigned long)tests
[i
].byte_len
);
258 current_state
= "length";
259 length_sz
= (*length
) (tests
[i
].val
);
260 if (sz
!= length_sz
) {
261 printf ("length for %s is bad (%lu != %lu)\n",
262 tests
[i
].name
, (unsigned long)length_sz
, (unsigned long)sz
);
267 current_state
= "memcmp";
268 if (memcmp (buf
, tests
[i
].bytes
, tests
[i
].byte_len
) != 0) {
269 printf ("encoding of %s has bad bytes:\n"
270 "correct: ", tests
[i
].name
);
271 print_bytes ((unsigned char *)tests
[i
].bytes
, tests
[i
].byte_len
);
272 printf ("\nactual: ");
273 print_bytes (buf
, sz
);
276 rk_dumpdata("correct", tests
[i
].bytes
, tests
[i
].byte_len
);
277 rk_dumpdata("actual", buf
, sz
);
284 buf2
= map_alloc(OVERRUN
, buf
, sz
, &buf2_map
);
286 current_state
= "decode";
287 ret
= (*decode
) (buf2
, sz
, data
, &consumed_sz
);
289 printf ("decoding of %s failed %d\n", tests
[i
].name
, ret
);
293 if (sz
!= consumed_sz
) {
294 printf ("different length decoding %s (%ld != %ld)\n",
296 (unsigned long)sz
, (unsigned long)consumed_sz
);
300 current_state
= "cmp";
301 if ((*cmp
)(data
, tests
[i
].val
) != 0) {
302 printf ("%s: comparison failed\n", tests
[i
].name
);
307 current_state
= "copy";
309 to
= emalloc(data_size
);
310 ret
= (*copy
)(data
, to
);
312 printf ("copy of %s failed %d\n", tests
[i
].name
, ret
);
317 current_state
= "cmp-copy";
318 if ((*cmp
)(data
, to
) != 0) {
319 printf ("%s: copy comparison failed\n", tests
[i
].name
);
325 current_state
= "free";
334 current_state
= "free";
335 map_free(buf_map
, tests
[i
].name
, "encode");
336 map_free(buf2_map
, tests
[i
].name
, "decode");
337 map_free(data_map
, tests
[i
].name
, "data");
339 #ifdef HAVE_SIGACTION
340 sigaction (SIGSEGV
, &osa
, NULL
);
343 current_state
= "done";
350 * a test size (byte_len) of -1 means that the test tries to trigger a
351 * integer overflow (and later a malloc of to little memory), just
352 * allocate some memory and hope that is enough for that test.
356 generic_decode_fail (const struct test_case
*tests
,
359 int (ASN1CALL
*decode
)(unsigned char *, size_t, void *, size_t *))
365 struct map_page
*data_map
, *buf_map
;
367 #ifdef HAVE_SIGACTION
368 struct sigaction sa
, osa
;
371 for (i
= 0; i
< ntests
; ++i
) {
376 current_test
= tests
[i
].name
;
378 current_state
= "init";
380 #ifdef HAVE_SIGACTION
381 sigemptyset (&sa
.sa_mask
);
384 sa
.sa_flags
|= SA_RESETHAND
;
386 sa
.sa_handler
= segv_handler
;
387 sigaction (SIGSEGV
, &sa
, &osa
);
390 data
= map_alloc(OVERRUN
, NULL
, data_size
, &data_map
);
392 if (tests
[i
].byte_len
< 0xffffff && tests
[i
].byte_len
>= 0) {
393 sz
= tests
[i
].byte_len
;
394 bytes
= tests
[i
].bytes
;
400 buf
= map_alloc(OVERRUN
, bytes
, sz
, &buf_map
);
402 if (tests
[i
].byte_len
== -1)
405 current_state
= "decode";
406 ret
= (*decode
) (buf
, tests
[i
].byte_len
, data
, &sz
);
408 printf ("sucessfully decoded %s\n", tests
[i
].name
);
413 current_state
= "free";
415 map_free(buf_map
, tests
[i
].name
, "encode");
416 map_free(data_map
, tests
[i
].name
, "data");
418 #ifdef HAVE_SIGACTION
419 sigaction (SIGSEGV
, &osa
, NULL
);
422 current_state
= "done";