1/*
2 * Copyright (c) 2002 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the Institute nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include <config.h>
35
36#include <sys/types.h>
37#ifdef HAVE_SYS_MMAN_H
38#include <sys/mman.h>
39#endif
40#include <fcntl.h>
41
42#include "roken.h"
43#include "resolve.h"
44
45static unsigned char basic[] = {
46    0x12, 0x67, 0x84, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
47    0x03, 'f', 'o', 'o', 0x00,
48    0x00, 0x10, 0x00, 0x01,
49    0x03, 'f', 'o', 'o', 0x00,
50    0x00, 0x10, 0x00, 0x01,
51    0x00, 0x00, 0x12, 0x67, 0xff, 0xff
52};
53static size_t basic_len = 36;
54
55static unsigned char dns_srv__kerberos__udp_SU_SE_[] = {
56  0x24, 0x5a, 0x01, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
57  0x09, 0x5f, 0x6b, 0x65, 0x72, 0x62, 0x65, 0x72, 0x6f, 0x73, 0x04, 0x5f,
58  0x75, 0x64, 0x70, 0x02, 0x53, 0x55, 0x02, 0x53, 0x45, 0x00, 0x00, 0x21,
59  0x00, 0x01, 0x09, 0x5f, 0x6b, 0x65, 0x72, 0x62, 0x65, 0x72, 0x6f, 0x73,
60  0x04, 0x5f, 0x75, 0x64, 0x70, 0x02, 0x53, 0x55, 0x02, 0x53, 0x45, 0x00,
61  0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x20, 0x00, 0x0a,
62  0x00, 0x01, 0x00, 0x58, 0x0f, 0x6b, 0x64, 0x63, 0x2d, 0x70, 0x72, 0x6f,
63  0x64, 0x2d, 0x73, 0x6c, 0x61, 0x76, 0x65, 0x32, 0x02, 0x69, 0x74, 0x02,
64  0x73, 0x75, 0x02, 0x73, 0x65, 0x00, 0x09, 0x5f, 0x6b, 0x65, 0x72, 0x62,
65  0x65, 0x72, 0x6f, 0x73, 0x04, 0x5f, 0x75, 0x64, 0x70, 0x02, 0x53, 0x55,
66  0x02, 0x53, 0x45, 0x00, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4d,
67  0x00, 0x20, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x58, 0x0f, 0x6b, 0x64, 0x63,
68  0x2d, 0x70, 0x72, 0x6f, 0x64, 0x2d, 0x73, 0x6c, 0x61, 0x76, 0x65, 0x33,
69  0x02, 0x69, 0x74, 0x02, 0x73, 0x75, 0x02, 0x73, 0x65, 0x00
70};
71static size_t dns_srv__kerberos__udp_SU_SE__len = 166;
72
73static unsigned char dns_srv__kerberos__udp_KTH_SE_[] = {
74    0xf0, 0xc5, 0x01, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
75    0x09, 0x5f, 0x6b, 0x65, 0x72, 0x62, 0x65, 0x72, 0x6f, 0x73, 0x04, 0x5f,
76    0x75, 0x64, 0x70, 0x03, 0x4b, 0x54, 0x48, 0x02, 0x53, 0x45, 0x00, 0x00,
77    0x21, 0x00, 0x01, 0x09, 0x5f, 0x6b, 0x65, 0x72, 0x62, 0x65, 0x72, 0x6f,
78    0x73, 0x04, 0x5f, 0x75, 0x64, 0x70, 0x03, 0x4b, 0x54, 0x48, 0x02, 0x53,
79    0x45, 0x00, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x23, 0x2a, 0x00, 0x1e,
80    0x00, 0x01, 0x00, 0x00, 0x00, 0x58, 0x0b, 0x6b, 0x72, 0x62, 0x2d, 0x73,
81    0x6c, 0x61, 0x76, 0x65, 0x2d, 0x31, 0x03, 0x73, 0x79, 0x73, 0x03, 0x6b,
82    0x74, 0x68, 0x02, 0x73, 0x65, 0x00, 0x09, 0x5f, 0x6b, 0x65, 0x72, 0x62,
83    0x65, 0x72, 0x6f, 0x73, 0x04, 0x5f, 0x75, 0x64, 0x70, 0x03, 0x4b, 0x54,
84    0x48, 0x02, 0x53, 0x45, 0x00, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x23,
85    0x2a, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x05, 0x6b, 0x72,
86    0x62, 0x2d, 0x31, 0x03, 0x73, 0x79, 0x73, 0x03, 0x6b, 0x74, 0x68, 0x02,
87    0x73, 0x65, 0x00, 0x09, 0x5f, 0x6b, 0x65, 0x72, 0x62, 0x65, 0x72, 0x6f,
88    0x73, 0x04, 0x5f, 0x75, 0x64, 0x70, 0x03, 0x4b, 0x54, 0x48, 0x02, 0x53,
89    0x45, 0x00, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x23, 0x2a, 0x00, 0x1e,
90    0x00, 0x01, 0x00, 0x00, 0x00, 0x58, 0x0b, 0x6b, 0x72, 0x62, 0x2d, 0x73,
91    0x6c, 0x61, 0x76, 0x65, 0x2d, 0x32, 0x03, 0x73, 0x79, 0x73, 0x03, 0x6b,
92    0x74, 0x68, 0x02, 0x73, 0x65, 0x00
93};
94static size_t dns_srv__kerberos__udp_KTH_SE__len = 222;
95
96static unsigned char dns_srv__kerberos__udp_ATHENA_MIT_EDU_[] = {
97    0x6d, 0x4d, 0x01, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
98    0x09, 0x5f, 0x6b, 0x65, 0x72, 0x62, 0x65, 0x72, 0x6f, 0x73, 0x04, 0x5f,
99    0x75, 0x64, 0x70, 0x06, 0x41, 0x54, 0x48, 0x45, 0x4e, 0x41, 0x03, 0x4d,
100    0x49, 0x54, 0x03, 0x45, 0x44, 0x55, 0x00, 0x00, 0x21, 0x00, 0x01, 0x09,
101    0x5f, 0x6b, 0x65, 0x72, 0x62, 0x65, 0x72, 0x6f, 0x73, 0x04, 0x5f, 0x75,
102    0x64, 0x70, 0x06, 0x41, 0x54, 0x48, 0x45, 0x4e, 0x41, 0x03, 0x4d, 0x49,
103    0x54, 0x03, 0x45, 0x44, 0x55, 0x00, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00,
104    0x08, 0xcc, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x0a, 0x4b,
105    0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x2d, 0x31, 0x03, 0x4d, 0x49,
106    0x54, 0x03, 0x45, 0x44, 0x55, 0x00, 0x09, 0x5f, 0x6b, 0x65, 0x72, 0x62,
107    0x65, 0x72, 0x6f, 0x73, 0x04, 0x5f, 0x75, 0x64, 0x70, 0x06, 0x41, 0x54,
108    0x48, 0x45, 0x4e, 0x41, 0x03, 0x4d, 0x49, 0x54, 0x03, 0x45, 0x44, 0x55,
109    0x00, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x08, 0xcc, 0x00, 0x1a, 0x00,
110    0x00, 0x00, 0x00, 0x00, 0x58, 0x0a, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52,
111    0x4f, 0x53, 0x2d, 0x32, 0x03, 0x4d, 0x49, 0x54, 0x03, 0x45, 0x44, 0x55,
112    0x00, 0x09, 0x5f, 0x6b, 0x65, 0x72, 0x62, 0x65, 0x72, 0x6f, 0x73, 0x04,
113    0x5f, 0x75, 0x64, 0x70, 0x06, 0x41, 0x54, 0x48, 0x45, 0x4e, 0x41, 0x03,
114    0x4d, 0x49, 0x54, 0x03, 0x45, 0x44, 0x55, 0x00, 0x00, 0x21, 0x00, 0x01,
115    0x00, 0x00, 0x08, 0xcc, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58,
116    0x08, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x03, 0x4d, 0x49,
117    0x54, 0x03, 0x45, 0x44, 0x55, 0x00
118};
119static size_t dns_srv__kerberos__udp_ATHENA_MIT_EDU__len = 246;
120
121struct testcase {
122    unsigned char *buf;
123    size_t buf_len;
124};
125
126#ifndef MAP_FAILED
127#define MAP_FAILED (-1)
128#endif
129
130static sig_atomic_t val = 0;
131
132static RETSIGTYPE
133segv_handler(int sig)
134{
135    val = 1;
136}
137
138int
139main(int argc, char **argv)
140{
141#ifndef HAVE_MMAP
142    return 77;			/* signal to automake that this test
143                                   cannot be run */
144#else /* HAVE_MMAP */
145    size_t i, n, count = 10000;
146    int ret;
147    struct sigaction sa;
148
149    struct testcase tests[4];
150
151    memset(tests, 0, sizeof(tests));
152    tests[0].buf     = basic;
153    tests[0].buf_len = basic_len;
154    tests[1].buf     = dns_srv__kerberos__udp_SU_SE_;
155    tests[1].buf_len = dns_srv__kerberos__udp_SU_SE__len;
156    tests[2].buf     = dns_srv__kerberos__udp_KTH_SE_;
157    tests[2].buf_len = dns_srv__kerberos__udp_KTH_SE__len;
158    tests[3].buf     = dns_srv__kerberos__udp_ATHENA_MIT_EDU_;
159    tests[3].buf_len = dns_srv__kerberos__udp_ATHENA_MIT_EDU__len;
160
161
162    sigemptyset (&sa.sa_mask);
163    sa.sa_flags = 0;
164    sa.sa_handler = segv_handler;
165    sigaction (SIGSEGV, &sa, NULL);
166
167    size_t pagesize = getpagesize();
168
169    for (i = 0; val == 0 && i < sizeof(tests)/sizeof(tests[0]); ++i) {
170	const struct testcase *t = &tests[i];
171	struct rk_dns_reply *reply;
172	unsigned char *p1, *p2;
173	unsigned char *buf;
174
175	printf("test %lu: ", (unsigned long)i);
176
177	p1 = (unsigned char *)mmap(0, 2 * pagesize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
178	if (p1 == (unsigned char *)MAP_FAILED)
179	    err (1, "mmap");
180	p2 = p1 + pagesize;
181	ret = mprotect ((void *)p2, pagesize, 0);
182	if (ret < 0)
183	    err (1, "mprotect");
184	buf = p2 - t->buf_len;
185
186	for (n = 0; n < count; n++) {
187
188	    memcpy (buf, t->buf, t->buf_len);
189	    if (n != 0)
190		buf[n % t->buf_len] = arc4random();
191
192	    reply = rk_dns_parse_reply (buf, t->buf_len);
193	    if (reply) {
194		if(reply->q.type == rk_ns_t_srv)
195		    rk_dns_srv_order(reply);
196		rk_dns_free_data(reply);
197	    }
198	    if ((n % 1000) == 0)
199		printf("%d...", (int)n);
200	}
201	printf("\n");
202	ret = munmap ((void *)p1, 2 * pagesize);
203	if (ret < 0)
204	    err (1, "munmap");
205    }
206    return val;
207#endif /* HAVE_MMAP */
208}
209