1#import <darwintest.h> 2#import <darwintest_utils.h> 3#import <dispatch/dispatch.h> 4#import <net/pfkeyv2.h> 5#import <netinet6/ipsec.h> 6#import <arpa/inet.h> 7#import <NetworkExtension/NetworkExtensionPrivate.h> 8#import <System/net/bpf.h> 9#import <System/netinet/ip.h> 10#import <System/netinet/ip6.h> 11 12T_GLOBAL_META( 13 T_META_NAMESPACE("xnu.ipsec"), 14 T_META_ASROOT(true), 15 T_META_CHECK_LEAKS(false)); 16 17typedef enum { 18 TEST_INVALID = 0, 19 TEST_IPSEC_IPv4_ENCAPSULATE_PANIC = 1, 20 TEST_IPSEC_IPv6_ENCAPSULATE_PANIC = 2, 21} test_identifier; 22 23#define TEST_SRC_ADDRESS_IPv4 "10.0.0.2" 24#define TEST_DST_ADDRESS_IPv4 "10.0.0.3" 25#define TEST_IPSEC_IPv4_INTERFACE_ADDRESS "192.168.10.10" 26#define TEST_IPSEC_IPv6_INTERFACE_ADDRESS "fdd3:0f89:9afd:9b9c::1234" 27#define TEST_DELEGATE_IPSEC_INTERFACE_ADDRESS "192.168.20.10" 28#define TEST_IPSEC_IPv4_INTERFACE_MASK "255.255.255.255" 29#define TEST_IPSEC_IPv6_INTERFACE_MASK "ffff:ffff:ffff:ffff::" 30 31static test_identifier test_id = TEST_INVALID; 32static dispatch_source_t pfkey_source = NULL; 33static NEVirtualInterfaceRef ipsecInterface = NULL; 34static NEVirtualInterfaceRef delegateIPsecInterface = NULL; 35static int bpf_fd = -1; 36 37static void bpf_write(int fd); 38static void pfkey_cleanup(void); 39static void pfkey_process_message_test_encapsulate_panic(uint8_t **mhp, int pfkey_socket); 40 41static void(*const process_pfkey_message_tests[])(uint8_t * *mhp, int pfkey_socket) = 42{ 43 NULL, 44 pfkey_process_message_test_encapsulate_panic, // TEST_IPSEC_IPv4_ENCAPSULATE_PANIC 45 pfkey_process_message_test_encapsulate_panic, // TEST_IPSEC_IPv6_ENCAPSULATE_PANIC 46}; 47 48static void 49send_pkey_add_sa(int pfkey_socket, uint32_t spi, const char *src, const char *dst, int family) 50{ 51 uint8_t payload[MCLBYTES] __attribute__ ((aligned(32))); 52 bzero(payload, sizeof(payload)); 53 uint16_t tlen = 0; 54 55 struct sadb_msg *msg_payload = (struct sadb_msg *)payload; 56 msg_payload->sadb_msg_version = PF_KEY_V2; 57 msg_payload->sadb_msg_type = SADB_ADD; 58 msg_payload->sadb_msg_errno = 0; 59 msg_payload->sadb_msg_satype = SADB_SATYPE_ESP; 60 msg_payload->sadb_msg_len = PFKEY_UNIT64(tlen); 61 msg_payload->sadb_msg_reserved = 0; 62 msg_payload->sadb_msg_seq = 0; 63 msg_payload->sadb_msg_pid = (u_int32_t)getpid(); 64 tlen += sizeof(*msg_payload); 65 66 struct sadb_sa_2 *sa2_payload = (struct sadb_sa_2 *)(void *)(payload + tlen); 67 sa2_payload->sa.sadb_sa_len = PFKEY_UNIT64(sizeof(*sa2_payload)); 68 sa2_payload->sa.sadb_sa_exttype = SADB_EXT_SA; 69 sa2_payload->sa.sadb_sa_spi = htonl(spi); 70 sa2_payload->sa.sadb_sa_replay = 4; 71 sa2_payload->sa.sadb_sa_state = SADB_SASTATE_LARVAL; 72 sa2_payload->sa.sadb_sa_auth = SADB_X_AALG_SHA2_256; 73 sa2_payload->sa.sadb_sa_encrypt = SADB_X_EALG_AESCBC; 74 sa2_payload->sa.sadb_sa_flags |= (SADB_X_EXT_NATT | SADB_X_EXT_NATT_KEEPALIVE); 75 sa2_payload->sadb_sa_natt_src_port = htons(4500); 76 sa2_payload->sadb_sa_natt_port = 4500; 77 sa2_payload->sadb_sa_natt_interval = 20; 78 sa2_payload->sadb_sa_natt_offload_interval = 0; 79 tlen += sizeof(*sa2_payload); 80 81 struct sadb_x_sa2 *sa2_x_payload = (struct sadb_x_sa2 *)(void *)(payload + tlen); 82 sa2_x_payload->sadb_x_sa2_len = PFKEY_UNIT64(sizeof(*sa2_x_payload)); 83 sa2_x_payload->sadb_x_sa2_exttype = SADB_X_EXT_SA2; 84 sa2_x_payload->sadb_x_sa2_mode = IPSEC_MODE_TUNNEL; 85 sa2_x_payload->sadb_x_sa2_reqid = 0; 86 tlen += sizeof(*sa2_x_payload); 87 88 uint8_t prefixlen = (family == AF_INET) ? (sizeof(struct in_addr) << 3) : (sizeof(struct in6_addr) << 3); 89 90 struct sadb_address *src_address_payload = (struct sadb_address *)(void *)(payload + tlen); 91 src_address_payload->sadb_address_exttype = SADB_EXT_ADDRESS_SRC & 0xffff; 92 src_address_payload->sadb_address_proto = IPSEC_ULPROTO_ANY & 0xff; 93 src_address_payload->sadb_address_prefixlen = prefixlen; 94 src_address_payload->sadb_address_reserved = 0; 95 tlen += sizeof(*src_address_payload); 96 97 if (family == AF_INET) { 98 struct sockaddr_in *src4 = (struct sockaddr_in *)(void *)(payload + tlen); 99 T_QUIET; T_ASSERT_EQ_INT(inet_pton(AF_INET, src, &src4->sin_addr), 1, "src address fail"); 100 src4->sin_family = AF_INET; 101 src4->sin_len = sizeof(*src4); 102 uint16_t len = sizeof(*src_address_payload) + PFKEY_ALIGN8(src4->sin_len); 103 src_address_payload->sadb_address_len = PFKEY_UNIT64(len); 104 tlen += PFKEY_ALIGN8(src4->sin_len); 105 } else { 106 struct sockaddr_in6 *src6 = (struct sockaddr_in6 *)(void *)(payload + tlen); 107 T_QUIET; T_ASSERT_EQ_INT(inet_pton(AF_INET6, src, &src6->sin6_addr), 1, "src address fail"); 108 src6->sin6_family = AF_INET6; 109 src6->sin6_len = sizeof(*src6); 110 uint16_t len = sizeof(*src_address_payload) + PFKEY_ALIGN8(src6->sin6_len); 111 src_address_payload->sadb_address_len = PFKEY_UNIT64(len); 112 tlen += PFKEY_ALIGN8(src6->sin6_len); 113 } 114 115 struct sadb_address *dst_address_payload = (struct sadb_address *)(void *)(payload + tlen); 116 dst_address_payload->sadb_address_exttype = SADB_EXT_ADDRESS_DST & 0xffff; 117 dst_address_payload->sadb_address_proto = IPSEC_ULPROTO_ANY & 0xff; 118 dst_address_payload->sadb_address_prefixlen = prefixlen; 119 dst_address_payload->sadb_address_reserved = 0; 120 tlen += sizeof(*dst_address_payload); 121 122 if (family == AF_INET) { 123 struct sockaddr_in *dst4 = (struct sockaddr_in *)(void *)(payload + tlen); 124 T_QUIET; T_ASSERT_EQ_INT(inet_pton(AF_INET, dst, &dst4->sin_addr), 1, "dst address fail"); 125 dst4->sin_family = AF_INET; 126 dst4->sin_len = sizeof(*dst4); 127 uint16_t len = sizeof(*dst_address_payload) + PFKEY_ALIGN8(dst4->sin_len); 128 dst_address_payload->sadb_address_len = PFKEY_UNIT64(len); 129 tlen += PFKEY_ALIGN8(dst4->sin_len); 130 } else { 131 struct sockaddr_in6 *dst6 = (struct sockaddr_in6 *)(void *)(payload + tlen); 132 T_QUIET; T_ASSERT_EQ_INT(inet_pton(AF_INET6, dst, &dst6->sin6_addr), 1, "dst address fail"); 133 dst6->sin6_family = AF_INET6; 134 dst6->sin6_len = sizeof(*dst6); 135 uint16_t len = sizeof(*dst_address_payload) + PFKEY_ALIGN8(dst6->sin6_len); 136 dst_address_payload->sadb_address_len = PFKEY_UNIT64(len); 137 tlen += PFKEY_ALIGN8(dst6->sin6_len); 138 } 139 140 CFStringRef ipsecIfName = NEVirtualInterfaceCopyName(ipsecInterface); 141 T_QUIET; T_ASSERT_NOTNULL(ipsecIfName, "failed to get ipsec interface name"); 142 char ifname[IFNAMSIZ]; 143 CFStringGetCString(ipsecIfName, ifname, IFNAMSIZ, kCFStringEncodingUTF8); 144 145 CFStringRef delegateIPsecIfName = NEVirtualInterfaceCopyName(delegateIPsecInterface); 146 T_QUIET; T_ASSERT_NOTNULL(delegateIPsecIfName, "failed to get delegate ipsec interface name"); 147 char delegateIfname[IFNAMSIZ]; 148 CFStringGetCString(delegateIPsecIfName, delegateIfname, IFNAMSIZ, kCFStringEncodingUTF8); 149 150 struct sadb_x_ipsecif *ipsec_if_payload = (struct sadb_x_ipsecif *)(void *)(payload + tlen); 151 ipsec_if_payload->sadb_x_ipsecif_len = PFKEY_UNIT64(sizeof(*ipsec_if_payload)); 152 ipsec_if_payload->sadb_x_ipsecif_exttype = SADB_X_EXT_IPSECIF; 153 strncpy(ipsec_if_payload->sadb_x_ipsecif_ipsec_if, ifname, strlen(ifname)); 154 strncpy(ipsec_if_payload->sadb_x_ipsecif_outgoing_if, delegateIfname, strlen(delegateIfname)); 155 tlen += sizeof(*ipsec_if_payload); 156 157 struct sadb_key *encrypt_key_payload = (struct sadb_key *)(void *)(payload + tlen); 158 uint16_t len = sizeof(*encrypt_key_payload) + PFKEY_ALIGN8(32); 159 encrypt_key_payload->sadb_key_len = PFKEY_UNIT64(len); 160 encrypt_key_payload->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 161 encrypt_key_payload->sadb_key_bits = (uint16_t)(32 << 3); 162 encrypt_key_payload->sadb_key_reserved = 0; 163 tlen += sizeof(*encrypt_key_payload); 164 arc4random_buf(payload + tlen, 32); 165 tlen += PFKEY_ALIGN8(32); 166 167 struct sadb_key *auth_key_payload = (struct sadb_key *)(void *)(payload + tlen); 168 len = sizeof(*auth_key_payload) + PFKEY_ALIGN8(32); 169 auth_key_payload->sadb_key_len = PFKEY_UNIT64(len); 170 auth_key_payload->sadb_key_exttype = SADB_EXT_KEY_AUTH; 171 auth_key_payload->sadb_key_bits = (uint16_t)(32 << 3); 172 auth_key_payload->sadb_key_reserved = 0; 173 tlen += sizeof(*auth_key_payload); 174 arc4random_buf(payload + tlen, 32); 175 tlen += PFKEY_ALIGN8(32); 176 177 struct sadb_lifetime *hard_lifetime_payload = (struct sadb_lifetime *)(void *)(payload + tlen); 178 hard_lifetime_payload->sadb_lifetime_len = PFKEY_UNIT64(sizeof(*hard_lifetime_payload)); 179 hard_lifetime_payload->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; 180 tlen += sizeof(*hard_lifetime_payload); 181 182 struct sadb_lifetime *soft_lifetime_payload = (struct sadb_lifetime *)(void *)(payload + tlen); 183 soft_lifetime_payload->sadb_lifetime_len = PFKEY_UNIT64(sizeof(*soft_lifetime_payload)); 184 soft_lifetime_payload->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; 185 tlen += sizeof(*soft_lifetime_payload); 186 187 // Update the total length 188 msg_payload->sadb_msg_len = PFKEY_UNIT64(tlen); 189 T_QUIET; T_ASSERT_POSIX_SUCCESS(send(pfkey_socket, payload, (size_t)PFKEY_UNUNIT64(msg_payload->sadb_msg_len), 0), "pfkey send update sa"); 190} 191 192static void 193send_pfkey_flush_sa(int pfkey_socket) 194{ 195 uint8_t payload[MCLBYTES] __attribute__ ((aligned(32))); 196 bzero(payload, sizeof(payload)); 197 uint16_t tlen = 0; 198 199 struct sadb_msg *msg_payload = (struct sadb_msg *)payload; 200 msg_payload->sadb_msg_version = PF_KEY_V2; 201 msg_payload->sadb_msg_type = SADB_FLUSH; 202 msg_payload->sadb_msg_errno = 0; 203 msg_payload->sadb_msg_satype = SADB_SATYPE_UNSPEC; 204 msg_payload->sadb_msg_len = PFKEY_UNIT64(tlen); 205 msg_payload->sadb_msg_reserved = 0; 206 msg_payload->sadb_msg_seq = 0; 207 msg_payload->sadb_msg_pid = (u_int32_t)getpid(); 208 tlen += sizeof(*msg_payload); 209 210 // Update the total length 211 msg_payload->sadb_msg_len = PFKEY_UNIT64(tlen); 212 T_QUIET; T_ASSERT_POSIX_SUCCESS(send(pfkey_socket, payload, (size_t)PFKEY_UNUNIT64(msg_payload->sadb_msg_len), 0), "pfkey flush sa"); 213} 214 215static void 216pfkey_cleanup(void) 217{ 218 if (pfkey_source != NULL) { 219 int pfkey_socket = (int)dispatch_source_get_handle(pfkey_source); 220 if (pfkey_socket > 0) { 221 send_pfkey_flush_sa(pfkey_socket); 222 } 223 dispatch_source_cancel(pfkey_source); 224 pfkey_source = NULL; 225 } 226} 227 228static void 229pfkey_align(struct sadb_msg *msg, uint8_t **mhp) 230{ 231 struct sadb_ext *ext; 232 int i; 233 uint8_t *p; 234 uint8_t *ep; /* XXX should be passed from upper layer */ 235 236 /* validity check */ 237 T_QUIET; T_ASSERT_NOTNULL(msg, "pfkey align msg"); 238 T_QUIET; T_ASSERT_NOTNULL(mhp, "pfkey align mhp"); 239 240 /* initialize */ 241 for (i = 0; i < SADB_EXT_MAX + 1; i++) { 242 mhp[i] = NULL; 243 } 244 245 mhp[0] = (void *)msg; 246 247 /* initialize */ 248 p = (void *) msg; 249 ep = p + PFKEY_UNUNIT64(msg->sadb_msg_len); 250 251 /* skip base header */ 252 p += sizeof(struct sadb_msg); 253 254 while (p < ep) { 255 ext = (void *)p; 256 T_QUIET; T_ASSERT_GE_PTR((void *)ep, (void *)(p + sizeof(*ext)), "pfkey extension header beyond end of buffer"); 257 T_QUIET; T_ASSERT_GE_ULONG((unsigned long)PFKEY_EXTLEN(ext), sizeof(*ext), "pfkey extension shorter than extension header"); 258 T_QUIET; T_ASSERT_GE_PTR((void *)ep, (void *)(p + PFKEY_EXTLEN(ext)), "pfkey extension length beyond end of buffer"); 259 260 T_QUIET; T_EXPECT_NULL(mhp[ext->sadb_ext_type], "duplicate extension type %u payload", ext->sadb_ext_type); 261 262 /* set pointer */ 263 switch (ext->sadb_ext_type) { 264 case SADB_EXT_SA: 265 case SADB_EXT_LIFETIME_CURRENT: 266 case SADB_EXT_LIFETIME_HARD: 267 case SADB_EXT_LIFETIME_SOFT: 268 case SADB_EXT_ADDRESS_SRC: 269 case SADB_EXT_ADDRESS_DST: 270 case SADB_EXT_ADDRESS_PROXY: 271 case SADB_EXT_KEY_AUTH: 272 /* XXX should to be check weak keys. */ 273 case SADB_EXT_KEY_ENCRYPT: 274 /* XXX should to be check weak keys. */ 275 case SADB_EXT_IDENTITY_SRC: 276 case SADB_EXT_IDENTITY_DST: 277 case SADB_EXT_SENSITIVITY: 278 case SADB_EXT_PROPOSAL: 279 case SADB_EXT_SUPPORTED_AUTH: 280 case SADB_EXT_SUPPORTED_ENCRYPT: 281 case SADB_EXT_SPIRANGE: 282 case SADB_X_EXT_POLICY: 283 case SADB_X_EXT_SA2: 284 case SADB_EXT_SESSION_ID: 285 case SADB_EXT_SASTAT: 286#ifdef SADB_X_EXT_NAT_T_TYPE 287 case SADB_X_EXT_NAT_T_TYPE: 288 case SADB_X_EXT_NAT_T_SPORT: 289 case SADB_X_EXT_NAT_T_DPORT: 290 case SADB_X_EXT_NAT_T_OA: 291#endif 292#ifdef SADB_X_EXT_TAG 293 case SADB_X_EXT_TAG: 294#endif 295#ifdef SADB_X_EXT_PACKET 296 case SADB_X_EXT_PACKET: 297#endif 298 case SADB_X_EXT_IPSECIF: 299 case SADB_X_EXT_ADDR_RANGE_SRC_START: 300 case SADB_X_EXT_ADDR_RANGE_SRC_END: 301 case SADB_X_EXT_ADDR_RANGE_DST_START: 302 case SADB_X_EXT_ADDR_RANGE_DST_END: 303#ifdef SADB_MIGRATE 304 case SADB_EXT_MIGRATE_ADDRESS_SRC: 305 case SADB_EXT_MIGRATE_ADDRESS_DST: 306 case SADB_X_EXT_MIGRATE_IPSECIF: 307#endif 308 mhp[ext->sadb_ext_type] = (void *)ext; 309 break; 310 default: 311 T_FAIL("bad extension type %u", ext->sadb_ext_type); 312 T_END; 313 } 314 315 p += PFKEY_EXTLEN(ext); 316 } 317 318 T_QUIET; T_EXPECT_EQ_PTR((void *)ep, (void *)p, "invalid pfkey message length"); 319 return; 320} 321 322static void 323pfkey_process_message_test_encapsulate_panic(uint8_t **mhp, __unused int pfkey_socket) 324{ 325 struct sadb_msg *message = (struct sadb_msg *)(void *)mhp[0]; 326 static uint32_t spi = 0; 327 static uint8_t added_sa_counter = 0; 328 329 if (message->sadb_msg_pid != (uint32_t)getpid()) { 330 return; 331 } 332 333 if (message->sadb_msg_errno != 0) { 334 T_FAIL("SADB add SA received error %d", message->sadb_msg_errno); 335 T_END; 336 } 337 338 switch (message->sadb_msg_type) { 339 case SADB_ADD: 340 { 341 struct sadb_sa *sa_message = (struct sadb_sa *)(void *)mhp[SADB_EXT_SA]; 342 T_QUIET; T_ASSERT_NOTNULL(sa_message, "add sa message is NULL"); 343 spi = ntohl(sa_message->sadb_sa_spi); 344 T_LOG("added sa 0x%x", spi); 345 added_sa_counter++; 346 if (added_sa_counter == 2) { 347 bpf_write(bpf_fd); 348 } 349 break; 350 } 351 case SADB_FLUSH: 352 case SADB_X_SPDFLUSH: 353 break; 354 default: 355 T_FAIL("bad SADB message type %u", message->sadb_msg_type); 356 T_END; 357 } 358 return; 359} 360 361static void 362recv_pfkey_message(int pfkey_socket) 363{ 364 uint8_t buffer[8192] __attribute__((aligned(4))); 365 struct iovec iovecs[1] = { 366 { buffer, sizeof(buffer) }, 367 }; 368 struct msghdr msg = { 369 NULL, 370 0, 371 iovecs, 372 sizeof(iovecs) / sizeof(iovecs[0]), 373 NULL, 374 0, 375 0, 376 }; 377 378 do { 379 ssize_t result = -1; 380 memset(buffer, 0, sizeof(buffer)); 381 T_QUIET; T_ASSERT_POSIX_SUCCESS(result = recvmsg(pfkey_socket, &msg, 0), NULL); 382 383 if (result > 0) { 384 T_QUIET; T_ASSERT_GE_ULONG((size_t)result, sizeof(struct sadb_msg), "Invalid PFKey message size: %zu", result); 385 struct sadb_msg *hdr = (struct sadb_msg *)buffer; 386 uint8_t *mhp[SADB_EXT_MAX + 1]; 387 pfkey_align(hdr, mhp); 388 (*process_pfkey_message_tests[test_id])(mhp, pfkey_socket); 389 } else if (result == 0) { 390 T_LOG("PFKey socket received EOF"); 391 break; 392 } 393 } while (1); 394} 395 396static int 397pfkey_setup_socket(void) 398{ 399 int pfkey_socket = -1; 400 int bufsiz = 0; 401 const unsigned long newbufk = 1536; 402 unsigned long oldmax; 403 size_t oldmaxsize = sizeof(oldmax); 404 unsigned long newmax = newbufk * (1024 + 128); 405 406 T_QUIET; T_ASSERT_POSIX_SUCCESS(pfkey_socket = socket(PF_KEY, SOCK_RAW, PF_KEY_V2), NULL); 407 408 if (sysctlbyname("kern.ipc.maxsockbuf", &oldmax, &oldmaxsize, &newmax, sizeof(newmax)) != 0) { 409 bufsiz = 233016; /* Max allowed by default */ 410 } else { 411 bufsiz = newbufk * 1024; 412 } 413 414 T_QUIET; T_ASSERT_POSIX_SUCCESS(setsockopt(pfkey_socket, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz)), "pfkey set snd socket buf failed %d", bufsiz); 415 T_QUIET; T_ASSERT_POSIX_SUCCESS(setsockopt(pfkey_socket, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)), "pfkey set recv socket buf failed %d", bufsiz); 416 417 pfkey_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, (uintptr_t)pfkey_socket, 0, dispatch_get_main_queue()); 418 T_QUIET; T_ASSERT_NOTNULL(pfkey_source, "dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, ...)"); 419 dispatch_source_set_event_handler(pfkey_source, ^{ 420 recv_pfkey_message(pfkey_socket); 421 }); 422 dispatch_source_set_cancel_handler(pfkey_source, ^{ 423 close(pfkey_socket); 424 }); 425 dispatch_resume(pfkey_source); 426 return pfkey_socket; 427} 428 429static int 430bpf_new(void) 431{ 432 char bpfdev[256]; 433 int i; 434 int fd = -1; 435 436 for (i = 0; true; i++) { 437 snprintf(bpfdev, sizeof(bpfdev), "/dev/bpf%d", i); 438 fd = open(bpfdev, O_RDWR, 0); 439 if (fd >= 0) { 440 break; 441 } 442 if (errno != EBUSY) { 443 break; 444 } 445 } 446 return fd; 447} 448 449static int 450bpf_setif(int fd, const char *en_name) 451{ 452 struct ifreq ifr; 453 454 strlcpy(ifr.ifr_name, en_name, sizeof(ifr.ifr_name)); 455 return ioctl(fd, BIOCSETIF, &ifr); 456} 457 458static int 459bpf_sethdr_complete(int fd) 460{ 461 u_int8_t hdr_complete = 1; 462 return ioctl(fd, BIOCSHDRCMPLT, &hdr_complete); 463} 464 465static void 466bpf_write(int fd) 467{ 468 if (test_id == TEST_IPSEC_IPv4_ENCAPSULATE_PANIC) { 469 char buffer[500]; 470 struct ip *ipheader = (void *)buffer; 471 ipheader->ip_v = IPVERSION; 472 ipheader->ip_hl = (sizeof(struct ip) - 4) >> 2; 473 ipheader->ip_ttl = MAXTTL; 474 ipheader->ip_p = IPPROTO_UDP; 475 T_QUIET; T_ASSERT_POSIX_SUCCESS(write(fd, buffer, 500), "bpf write call failed"); 476 T_PASS("wrote bad ip header successfully"); 477 T_END; 478 } else if (test_id == TEST_IPSEC_IPv6_ENCAPSULATE_PANIC) { 479 struct ip6_hdr ip6 = {0}; 480 ip6.ip6_vfc |= IPV6_VERSION; 481 T_QUIET; T_ASSERT_POSIX_SUCCESS(write(fd, &ip6, sizeof(ip6) - 4), "bpf write call failed"); 482 T_PASS("wrote bad ipv6 header successfully"); 483 T_END; 484 } 485} 486 487static void 488bpf_socket_setup(void) 489{ 490 int status = -1; 491 492 bpf_fd = bpf_new(); 493 T_QUIET; T_ASSERT_NE(bpf_fd, -1, "failed to create bpf file descriptor"); 494 495 CFStringRef ipsecIfName = NEVirtualInterfaceCopyName(ipsecInterface); 496 T_QUIET; T_ASSERT_NOTNULL(ipsecIfName, "failed to get ipsec interface name"); 497 498 char ifname[IFNAMSIZ]; 499 CFStringGetCString(ipsecIfName, ifname, IFNAMSIZ, kCFStringEncodingUTF8); 500 501 status = bpf_setif(bpf_fd, ifname); 502 T_QUIET; T_ASSERT_NE(status, -1, "failed to set bpf interface"); 503 504 status = bpf_sethdr_complete(bpf_fd); 505 T_QUIET; T_ASSERT_NE(status, -1, "failed to set bpf header complete"); 506} 507 508static NEVirtualInterfaceRef 509ipsec_interface_setup(CFStringRef interfaceAddress, CFStringRef interfaceMask) 510{ 511 Boolean status = FALSE; 512 513 NEVirtualInterfaceRef interface = NEVirtualInterfaceCreate(NULL, kNEVirtualInterfaceValTypeIPSec, dispatch_get_main_queue(), NULL); 514 T_QUIET; T_ASSERT_NOTNULL(interface, "ipsec interface creation failed"); 515 status = NEVirtualInterfaceSetMTU(interface, 1400); 516 if (status == FALSE) { 517 T_FAIL("Failed to set MTU on ipsec interface"); 518 T_END; 519 } 520 521 status = NEVirtualInterfaceAddAddress(interface, interfaceAddress, interfaceMask); 522 if (status == FALSE) { 523 T_FAIL("Failed to set address on ipsec interface"); 524 T_END; 525 } 526 527 CFStringRef ipsecIfName = NEVirtualInterfaceCopyName(interface); 528 T_QUIET; T_ASSERT_NOTNULL(ipsecIfName, "failed to get ipsec interface name"); 529 530 char ifname[IFNAMSIZ]; 531 CFStringGetCString(ipsecIfName, ifname, IFNAMSIZ, kCFStringEncodingUTF8); 532 533 T_LOG("%s interface setup", ifname); 534 return interface; 535} 536 537static void 538ipsec_interface_set_delegate(NEVirtualInterfaceRef interface, CFStringRef delegateInterfaceName) 539{ 540 Boolean status = NEVirtualInterfaceSetDelegateInterface(interface, delegateInterfaceName); 541 if (status == FALSE) { 542 T_FAIL("Failed to set delegate on ipsec interface"); 543 T_END; 544 } 545 546 return; 547} 548 549static void 550ipsec_cleanup(void) 551{ 552 pfkey_cleanup(); 553 554 if (ipsecInterface != NULL) { 555 NEVirtualInterfaceInvalidate(ipsecInterface); 556 ipsecInterface = NULL; 557 } 558 559 if (delegateIPsecInterface != NULL) { 560 NEVirtualInterfaceInvalidate(delegateIPsecInterface); 561 delegateIPsecInterface = NULL; 562 } 563 564 if (bpf_fd != -1) { 565 close(bpf_fd); 566 bpf_fd = -1; 567 } 568} 569 570T_DECL(ipsec_ipv4_encapsulate_panic_63139357, "ipsec: outer ip header length less than 20") 571{ 572 test_id = TEST_IPSEC_IPv4_ENCAPSULATE_PANIC; 573 574 T_ATEND(ipsec_cleanup); 575 576 ipsecInterface = ipsec_interface_setup(CFSTR(TEST_IPSEC_IPv4_INTERFACE_ADDRESS), CFSTR(TEST_IPSEC_IPv4_INTERFACE_MASK)); 577 delegateIPsecInterface = ipsec_interface_setup(CFSTR(TEST_DELEGATE_IPSEC_INTERFACE_ADDRESS), CFSTR(TEST_IPSEC_IPv4_INTERFACE_MASK)); 578 579 CFStringRef delegateIPsecIfName = NEVirtualInterfaceCopyName(delegateIPsecInterface); 580 T_QUIET; T_ASSERT_NOTNULL(delegateIPsecIfName, "failed to get ipsec interface name"); 581 ipsec_interface_set_delegate(ipsecInterface, delegateIPsecIfName); 582 583 bpf_socket_setup(); 584 585 int pfkey_socket = pfkey_setup_socket(); 586 send_pfkey_flush_sa(pfkey_socket); 587 588 send_pkey_add_sa(pfkey_socket, 0x12345678, TEST_SRC_ADDRESS_IPv4, TEST_DST_ADDRESS_IPv4, AF_INET); 589 send_pkey_add_sa(pfkey_socket, 0x23456789, TEST_SRC_ADDRESS_IPv4, TEST_DST_ADDRESS_IPv4, AF_INET); 590 591 dispatch_main(); 592} 593 594T_DECL(ipsec_ipv6_encapsulate_panic_63139357, "ipsec: payload less than IPv6 header") 595{ 596 test_id = TEST_IPSEC_IPv6_ENCAPSULATE_PANIC; 597 598 T_ATEND(ipsec_cleanup); 599 600 ipsecInterface = ipsec_interface_setup(CFSTR(TEST_IPSEC_IPv6_INTERFACE_ADDRESS), CFSTR(TEST_IPSEC_IPv6_INTERFACE_MASK)); 601 delegateIPsecInterface = ipsec_interface_setup(CFSTR(TEST_DELEGATE_IPSEC_INTERFACE_ADDRESS), CFSTR(TEST_IPSEC_IPv4_INTERFACE_MASK)); 602 603 CFStringRef delegateIPsecIfName = NEVirtualInterfaceCopyName(delegateIPsecInterface); 604 T_QUIET; T_ASSERT_NOTNULL(delegateIPsecIfName, "failed to get ipsec interface name"); 605 ipsec_interface_set_delegate(ipsecInterface, delegateIPsecIfName); 606 607 bpf_socket_setup(); 608 609 int pfkey_socket = pfkey_setup_socket(); 610 send_pfkey_flush_sa(pfkey_socket); 611 612 send_pkey_add_sa(pfkey_socket, 0x12345678, TEST_SRC_ADDRESS_IPv4, TEST_DST_ADDRESS_IPv4, AF_INET); 613 send_pkey_add_sa(pfkey_socket, 0x23456789, TEST_SRC_ADDRESS_IPv4, TEST_DST_ADDRESS_IPv4, AF_INET); 614 615 dispatch_main(); 616} 617