2 * Check decoding of sockaddr structures
4 * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
5 * Copyright (c) 2016-2017 The strace developers.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
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 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include <sys/socket.h>
38 #include <arpa/inet.h>
39 #include <netinet/in.h>
41 #include <linux/if_arp.h>
42 #include <linux/if_ether.h>
43 #include <linux/if_packet.h>
44 #include <linux/ipx.h>
45 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
46 # include <bluetooth/bluetooth.h>
47 # include <bluetooth/hci.h>
48 # include <bluetooth/l2cap.h>
49 # include <bluetooth/rfcomm.h>
50 # include <bluetooth/sco.h>
53 #ifdef HAVE_IF_INDEXTONAME
54 /* <linux/if.h> used to conflict with <net/if.h> */
55 extern unsigned int if_nametoindex(const char *);
61 TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_un, un);
62 un->sun_family = AF_UNIX;
63 memset(un->sun_path, '0', sizeof(un->sun_path));
64 unsigned int len = sizeof(*un);
65 int ret = connect(-1, (void *) un, len);
66 printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
67 ", %u) = %d EBADF (%m)\n",
68 (int) sizeof(un->sun_path), 0, len, ret);
71 ret = connect(-1, (void *) un, len);
72 printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%u\"}, %u)"
73 " = %d EBADF (%m)\n", 0, len, ret);
77 ret = connect(-1, (void *) un, len);
78 printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"\\0\\001%.*u\"}"
79 ", %u) = %d EBADF (%m)\n",
80 (int) sizeof(un->sun_path) - 3, 0, len, ret);
82 un = ((void *) un) - 2;
83 un->sun_family = AF_UNIX;
84 memset(un->sun_path, '0', sizeof(un->sun_path));
85 len = sizeof(*un) + 2;
86 ret = connect(-1, (void *) un, len);
87 printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
88 ", %u) = %d EBADF (%m)\n",
89 (int) sizeof(un->sun_path), 0, len, ret);
92 ret = connect(-1, (void *) un, len);
93 printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
94 ", %u) = %d EBADF (%m)\n",
95 (int) sizeof(un->sun_path) - 1, 0, len, ret);
97 un = ((void *) un) + 4;
98 un->sun_family = AF_UNIX;
99 len = sizeof(*un) - 2;
100 ret = connect(-1, (void *) un, len);
101 printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
102 ", %u) = %d EBADF (%m)\n",
103 (int) sizeof(un->sun_path) - 2, 0, len, ret);
106 ret = connect(-1, (void *) un, len);
107 printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
108 ", %u) = %d EBADF (%m)\n",
109 (int) sizeof(un->sun_path) - 3, 0, len, ret);
112 ret = connect(-1, (void *) un, len);
113 printf("connect(-1, %p, %u) = %d EBADF (%m)\n", un, len, ret);
115 un = tail_alloc(sizeof(struct sockaddr_storage));
116 un->sun_family = AF_UNIX;
117 memset(un->sun_path, '0', sizeof(un->sun_path));
118 len = sizeof(struct sockaddr_storage) + 1;
119 ret = connect(-1, (void *) un, len);
120 printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
121 ", %u) = %d EBADF (%m)\n",
122 (int) sizeof(un->sun_path), 0, len, ret);
125 ret = connect(-1, (void *) un, len);
126 printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
127 ", %u) = %d EBADF (%m)\n",
128 (int) sizeof(un->sun_path) - 1, 0, len, ret);
134 const unsigned short h_port = 12345;
135 static const char h_addr[] = "12.34.56.78";
137 TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_in, in);
138 in->sin_family = AF_INET;
139 in->sin_port = htons(h_port);
140 in->sin_addr.s_addr = inet_addr(h_addr);
141 unsigned int len = sizeof(*in);
142 int ret = connect(-1, (void *) in, len);
143 printf("connect(-1, {sa_family=AF_INET, sin_port=htons(%hu)"
144 ", sin_addr=inet_addr(\"%s\")}, %u) = %d EBADF (%m)\n",
145 h_port, h_addr, len, ret);
147 in = ((void *) in) - 4;
148 in->sin_family = AF_INET;
149 in->sin_port = htons(h_port);
150 in->sin_addr.s_addr = inet_addr(h_addr);
151 len = sizeof(*in) + 4;
152 ret = connect(-1, (void *) in, len);
153 printf("connect(-1, {sa_family=AF_INET, sin_port=htons(%hu)"
154 ", sin_addr=inet_addr(\"%s\")}, %u) = %d EBADF (%m)\n",
155 h_port, h_addr, len, ret);
157 in = ((void *) in) + 8;
158 in->sin_family = AF_INET;
160 in->sin_addr.s_addr = 0;
161 len = sizeof(*in) - 4;
162 ret = connect(-1, (void *) in, len);
163 printf("connect(-1, {sa_family=AF_INET, sa_data=\"%s\"}, %u)"
164 " = %d EBADF (%m)\n",
165 "\\0\\0\\0\\0\\0\\0\\377\\377\\377\\377",
169 ret = connect(-1, (void *) in, len);
170 printf("connect(-1, %p, %u) = %d EBADF (%m)\n", in, len, ret);
174 check_in6_linklocal(struct sockaddr_in6 *const in6, const char *const h_addr)
176 inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
178 in6->sin6_scope_id = 0xfacefeed;
179 unsigned int len = sizeof(*in6);
180 int ret = connect(-1, (void *) in6, len);
181 printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
182 ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
183 ", sin6_flowinfo=htonl(%u)"
184 ", sin6_scope_id=%u}, %u)"
185 " = %d EBADF (%m)\n",
186 ntohs(in6->sin6_port), h_addr,
187 ntohl(in6->sin6_flowinfo), in6->sin6_scope_id, len, ret);
189 #ifdef HAVE_IF_INDEXTONAME
190 in6->sin6_scope_id = if_nametoindex("lo");
191 if (in6->sin6_scope_id) {
192 ret = connect(-1, (void *) in6, len);
193 printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
194 ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
195 ", sin6_flowinfo=htonl(%u)"
196 ", sin6_scope_id=if_nametoindex(\"lo\")}, %u)"
197 " = %d EBADF (%m)\n",
198 ntohs(in6->sin6_port), h_addr,
199 ntohl(in6->sin6_flowinfo), len, ret);
207 const unsigned short h_port = 12345;
208 const unsigned int h_flowinfo = 1234567890;
209 static const char h_addr[] = "12:34:56:78:90:ab:cd:ef";
211 TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_in6, in6);
212 in6->sin6_family = AF_INET6;
213 in6->sin6_port = htons(h_port);
214 in6->sin6_flowinfo = htonl(h_flowinfo);
215 inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
216 in6->sin6_scope_id = 0xfacefeed;
217 unsigned int len = sizeof(*in6);
218 int ret = connect(-1, (void *) in6, len);
219 printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
220 ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
221 ", sin6_flowinfo=htonl(%u), sin6_scope_id=%u}, %u)"
222 " = %d EBADF (%m)\n",
223 h_port, h_addr, h_flowinfo, in6->sin6_scope_id, len, ret);
225 check_in6_linklocal(in6, "fe80::");
226 check_in6_linklocal(in6, "ff42::");
228 in6 = ((void *) in6) - 4;
229 in6->sin6_family = AF_INET6;
230 in6->sin6_port = htons(h_port);
231 in6->sin6_flowinfo = htonl(h_flowinfo);
232 inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
233 in6->sin6_scope_id = 0xfacefeed;
234 len = sizeof(*in6) + 4;
235 ret = connect(-1, (void *) in6, len);
236 printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
237 ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
238 ", sin6_flowinfo=htonl(%u), sin6_scope_id=%u}, %u)"
239 " = %d EBADF (%m)\n",
240 h_port, h_addr, h_flowinfo, in6->sin6_scope_id, len, ret);
242 in6 = ((void *) in6) + 4 + sizeof(in6->sin6_scope_id);
243 in6->sin6_family = AF_INET6;
244 in6->sin6_port = htons(h_port);
245 in6->sin6_flowinfo = htonl(h_flowinfo);
246 inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
247 len = sizeof(*in6) - sizeof(in6->sin6_scope_id);
248 ret = connect(-1, (void *) in6, len);
249 printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
250 ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
251 ", sin6_flowinfo=htonl(%u)}, %u)"
252 " = %d EBADF (%m)\n",
253 h_port, h_addr, h_flowinfo, len, ret);
255 in6 = ((void *) in6) + 4;
256 in6->sin6_family = AF_INET6;
258 in6->sin6_flowinfo = 0;
259 memset(&in6->sin6_addr, '0', sizeof(in6->sin6_addr) - 4);
260 len = sizeof(*in6) - sizeof(in6->sin6_scope_id) - 4;
261 ret = connect(-1, (void *) in6, len);
262 printf("connect(-1, {sa_family=AF_INET6"
263 ", sa_data=\"\\0\\0\\0\\0\\0\\000%.*u\"}, %u)"
264 " = %d EBADF (%m)\n",
265 (int) (len - offsetof(struct sockaddr_in6, sin6_addr)), 0,
268 len = sizeof(*in6) - sizeof(in6->sin6_scope_id);
269 ret = connect(-1, (void *) in6, len);
270 printf("connect(-1, %p, %u) = %d EBADF (%m)\n", in6, len, ret);
276 const unsigned short h_port = 12345;
277 const unsigned int h_network = 0xfacefeed;
278 struct sockaddr_ipx c_ipx = {
279 .sipx_family = AF_IPX,
280 .sipx_port = htons(h_port),
281 .sipx_network = htonl(h_network),
282 .sipx_node = "ABCDEF",
285 void *ipx = tail_memdup(&c_ipx, sizeof(c_ipx));
286 unsigned int len = sizeof(c_ipx);
287 int ret = connect(-1, ipx, len);
288 printf("connect(-1, {sa_family=AF_IPX, sipx_port=htons(%u)"
289 ", sipx_network=htonl(%#x)"
290 ", sipx_node=[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x]"
291 ", sipx_type=%#02x}, %u) = %d EBADF (%m)\n",
293 c_ipx.sipx_node[0], c_ipx.sipx_node[1],
294 c_ipx.sipx_node[2], c_ipx.sipx_node[3],
295 c_ipx.sipx_node[4], c_ipx.sipx_node[5],
296 c_ipx.sipx_type, len, ret);
302 TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_nl, nl);
303 nl->nl_family = AF_NETLINK;
304 nl->nl_pid = 1234567890;
305 nl->nl_groups = 0xfacefeed;
306 unsigned int len = sizeof(*nl);
307 int ret = connect(-1, (void *) nl, len);
308 printf("connect(-1, {sa_family=AF_NETLINK, nl_pid=%d"
309 ", nl_groups=%#08x}, %u) = %d EBADF (%m)\n",
310 nl->nl_pid, nl->nl_groups, len, ret);
312 nl = ((void *) nl) - 4;
313 nl->nl_family = AF_NETLINK;
314 nl->nl_pid = 1234567890;
315 nl->nl_groups = 0xfacefeed;
316 len = sizeof(*nl) + 4;
317 ret = connect(-1, (void *) nl, len);
318 printf("connect(-1, {sa_family=AF_NETLINK, nl_pid=%d"
319 ", nl_groups=%#08x}, %u) = %d EBADF (%m)\n",
320 nl->nl_pid, nl->nl_groups, len, ret);
326 struct sockaddr_ll c_ll = {
327 .sll_family = AF_PACKET,
328 .sll_protocol = htons(ETH_P_ALL),
329 .sll_ifindex = 0xfacefeed,
330 .sll_hatype = ARPHRD_ETHER,
331 .sll_pkttype = PACKET_HOST,
332 .sll_halen = sizeof(c_ll.sll_addr),
333 .sll_addr = "abcdefgh"
335 void *ll = tail_memdup(&c_ll, sizeof(c_ll));
336 unsigned int len = sizeof(c_ll);
337 int ret = connect(-1, ll, len);
338 printf("connect(-1, {sa_family=AF_PACKET"
339 ", sll_protocol=htons(ETH_P_ALL)"
340 ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
341 ", sll_pkttype=PACKET_HOST, sll_halen=%u, sll_addr="
342 "[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x]"
343 "}, %u) = %d EBADF (%m)\n",
344 c_ll.sll_ifindex, c_ll.sll_halen,
345 c_ll.sll_addr[0], c_ll.sll_addr[1],
346 c_ll.sll_addr[2], c_ll.sll_addr[3],
347 c_ll.sll_addr[4], c_ll.sll_addr[5],
348 c_ll.sll_addr[6], c_ll.sll_addr[7],
351 ((struct sockaddr_ll *) ll)->sll_halen++;
352 ret = connect(-1, ll, len);
353 printf("connect(-1, {sa_family=AF_PACKET"
354 ", sll_protocol=htons(ETH_P_ALL)"
355 ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
356 ", sll_pkttype=PACKET_HOST, sll_halen=%u, sll_addr="
357 "[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, ...]"
358 "}, %u) = %d EBADF (%m)\n",
359 c_ll.sll_ifindex, c_ll.sll_halen + 1,
360 c_ll.sll_addr[0], c_ll.sll_addr[1],
361 c_ll.sll_addr[2], c_ll.sll_addr[3],
362 c_ll.sll_addr[4], c_ll.sll_addr[5],
363 c_ll.sll_addr[6], c_ll.sll_addr[7],
366 ((struct sockaddr_ll *) ll)->sll_halen = 0;
367 ret = connect(-1, ll, len);
368 printf("connect(-1, {sa_family=AF_PACKET"
369 ", sll_protocol=htons(ETH_P_ALL)"
370 ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
371 ", sll_pkttype=PACKET_HOST, sll_halen=0}, %u)"
372 " = %d EBADF (%m)\n", c_ll.sll_ifindex, len, ret);
374 #ifdef HAVE_IF_INDEXTONAME
375 const int id = if_nametoindex("lo");
377 ((struct sockaddr_ll *) ll)->sll_ifindex = id;
378 ret = connect(-1, ll, len);
379 printf("connect(-1, {sa_family=AF_PACKET"
380 ", sll_protocol=htons(ETH_P_ALL)"
381 ", sll_ifindex=if_nametoindex(\"lo\")"
382 ", sll_hatype=ARPHRD_ETHER"
383 ", sll_pkttype=PACKET_HOST, sll_halen=0}, %u)"
384 " = %d EBADF (%m)\n", len, ret);
389 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
393 const unsigned short h_port = 12345;
394 TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_hci, hci);
395 hci->hci_family = AF_BLUETOOTH;
396 hci->hci_dev = htobs(h_port);
397 hci->hci_channel = HCI_CHANNEL_RAW;
398 unsigned int len = sizeof(*hci);
399 int ret = connect(-1, (void *) hci, len);
400 printf("connect(-1, {sa_family=AF_BLUETOOTH, hci_dev=htobs(%hu)"
401 ", hci_channel=HCI_CHANNEL_RAW}, %u) = %d EBADF (%m)\n",
408 const struct sockaddr_sco c_sco = {
409 .sco_family = AF_BLUETOOTH,
410 .sco_bdaddr.b = "abcdef"
412 void *sco = tail_memdup(&c_sco, sizeof(c_sco));
413 unsigned int len = sizeof(c_sco);
414 int ret = connect(-1, sco, len);
415 printf("connect(-1, {sa_family=AF_BLUETOOTH"
416 ", sco_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
417 "}, %u) = %d EBADF (%m)\n",
418 c_sco.sco_bdaddr.b[0], c_sco.sco_bdaddr.b[1],
419 c_sco.sco_bdaddr.b[2], c_sco.sco_bdaddr.b[3],
420 c_sco.sco_bdaddr.b[4], c_sco.sco_bdaddr.b[5],
427 const struct sockaddr_rc c_rc = {
428 .rc_family = AF_BLUETOOTH,
429 .rc_bdaddr.b = "abcdef",
432 void *rc = tail_memdup(&c_rc, sizeof(c_rc));
433 unsigned int len = sizeof(c_rc);
434 int ret = connect(-1, rc, len);
435 printf("connect(-1, {sa_family=AF_BLUETOOTH"
436 ", rc_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
437 ", rc_channel=%u}, %u) = %d EBADF (%m)\n",
438 c_rc.rc_bdaddr.b[0], c_rc.rc_bdaddr.b[1],
439 c_rc.rc_bdaddr.b[2], c_rc.rc_bdaddr.b[3],
440 c_rc.rc_bdaddr.b[4], c_rc.rc_bdaddr.b[5],
441 c_rc.rc_channel, len, ret);
447 const unsigned short h_psm = 12345;
448 const unsigned short h_cid = 13579;
449 const struct sockaddr_l2 c_l2 = {
450 .l2_family = AF_BLUETOOTH,
451 .l2_psm = htobs(h_psm),
452 .l2_bdaddr.b = "abcdef",
453 .l2_cid = htobs(h_cid),
456 void *l2 = tail_memdup(&c_l2, sizeof(c_l2));
457 unsigned int len = sizeof(c_l2);
458 int ret = connect(-1, l2, len);
459 printf("connect(-1, {sa_family=AF_BLUETOOTH"
460 ", l2_psm=htobs(%hu)"
461 ", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
462 ", l2_cid=htobs(%hu), l2_bdaddr_type=%u}"
463 ", %u) = %d EBADF (%m)\n", h_psm,
464 c_l2.l2_bdaddr.b[0], c_l2.l2_bdaddr.b[1],
465 c_l2.l2_bdaddr.b[2], c_l2.l2_bdaddr.b[3],
466 c_l2.l2_bdaddr.b[4], c_l2.l2_bdaddr.b[5],
467 h_cid, c_l2.l2_bdaddr_type, len, ret);
476 struct sockaddr_storage *st;
477 } u = { .st = tail_alloc(sizeof(*u.st)) };
478 memset(u.st, '0', sizeof(*u.st));
479 u.sa->sa_family = 0xff;
480 unsigned int len = sizeof(*u.st) + 8;
481 int ret = connect(-1, (void *) u.st, len);
482 printf("connect(-1, {sa_family=%#x /* AF_??? */, sa_data=\"%.*u\"}"
483 ", %u) = %d EBADF (%m)\n", u.sa->sa_family,
484 (int) (sizeof(*u.st) - sizeof(u.sa->sa_family)), 0, len, ret);
487 len = sizeof(u.sa->sa_family) + 1;
488 ret = connect(-1, (void *) u.st, len);
489 printf("connect(-1, {sa_family=AF_UNSPEC, sa_data=\"0\"}, %u)"
490 " = %d EBADF (%m)\n", len, ret);
492 u.sa->sa_family = AF_BLUETOOTH;
494 ret = connect(-1, (void *) u.st, len);
495 printf("connect(-1, {sa_family=AF_BLUETOOTH, sa_data=\"00\"}, %u)"
496 " = %d EBADF (%m)\n", len, ret);
508 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
516 puts("+++ exited with 0 +++");