1 /* 2 * Copyright (c) 2020 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29 #include <vsock_helpers.h> 30 31 T_GLOBAL_META( 32 T_META_RUN_CONCURRENTLY(true), 33 T_META_NAMESPACE("xnu.vsock") 34 ); 35 36 /* New Socket */ 37 38 T_DECL(new_socket_getsockname, "vsock new - getsockname") 39 { 40 int socket = vsock_new_socket(); 41 42 struct sockaddr_vm addr; 43 socklen_t length = sizeof(struct sockaddr_vm); 44 int result = getsockname(socket, (struct sockaddr *)&addr, &length); 45 T_ASSERT_POSIX_SUCCESS(result, "vsock getsockname"); 46 T_ASSERT_EQ_INT(addr.svm_port, VMADDR_PORT_ANY, "name is any port"); 47 T_ASSERT_EQ_INT(addr.svm_cid, VMADDR_CID_ANY, "name is any cid"); 48 } 49 50 T_DECL(new_socket_getpeername, "vsock new - getpeername") 51 { 52 int socket = vsock_new_socket(); 53 54 struct sockaddr_vm addr; 55 socklen_t length = sizeof(struct sockaddr_vm); 56 int result = getpeername(socket, (struct sockaddr *)&addr, &length); 57 T_ASSERT_POSIX_FAILURE(result, ENOTCONN, "vsock getpeername"); 58 } 59 60 /* Ioctl */ 61 62 T_DECL(ioctl_cid, "vsock ioctl cid") 63 { 64 int socket = vsock_new_socket(); 65 vsock_get_local_cid(socket); 66 } 67 68 /* Socketpair */ 69 70 T_DECL(socketpair, "vsock socketpair") 71 { 72 int pair[2]; 73 int error = socketpair(AF_VSOCK, SOCK_STREAM, 0, pair); 74 if (error < 0 && errno == ENODEV) { 75 T_SKIP("no vsock transport available"); 76 } 77 T_ASSERT_POSIX_FAILURE(error, EOPNOTSUPP, "vsock socketpair not supported"); 78 } 79 80 /* Bind */ 81 82 T_DECL(bind, "vsock bind to specific port") 83 { 84 int socket; 85 struct sockaddr_vm addr; 86 const uint32_t port = vsock_get_available_port(); 87 int result = vsock_bind(VMADDR_CID_ANY, port, &addr, &socket); 88 T_ASSERT_POSIX_SUCCESS(result, "vsock bind to specific port"); 89 } 90 91 T_DECL(bind_any, "vsock bind to any port") 92 { 93 int socket; 94 struct sockaddr_vm addr; 95 int result = vsock_bind(VMADDR_CID_ANY, VMADDR_PORT_ANY, &addr, &socket); 96 T_ASSERT_POSIX_SUCCESS(result, "vsock bind to any port"); 97 } 98 99 T_DECL(bind_getsockname, "vsock bind - getsockname") 100 { 101 int socket; 102 struct sockaddr_vm addr; 103 const uint32_t port = VMADDR_PORT_ANY; 104 const uint32_t cid = VMADDR_CID_ANY; 105 int result = vsock_bind(cid, port, &addr, &socket); 106 T_ASSERT_POSIX_SUCCESS(result, "vsock bind to any port"); 107 108 struct sockaddr_vm bound_addr = vsock_getsockname(socket); 109 T_ASSERT_NE_INT(bound_addr.svm_port, port, "bound to unique local port"); 110 T_ASSERT_EQ_INT(bound_addr.svm_cid, cid, "bound to any cid"); 111 } 112 113 T_DECL(bind_hypervisor, "vsock do not bind to hypervisor cid") 114 { 115 int socket; 116 struct sockaddr_vm addr; 117 int result = vsock_bind(VMADDR_CID_HYPERVISOR, VMADDR_PORT_ANY, &addr, &socket); 118 T_ASSERT_POSIX_FAILURE(result, EADDRNOTAVAIL, "vsock do not bind to hypervisor cid"); 119 } 120 121 T_DECL(bind_reserved, "vsock do not bind to reserved cid") 122 { 123 int socket; 124 struct sockaddr_vm addr; 125 int result = vsock_bind(VMADDR_CID_RESERVED, VMADDR_PORT_ANY, &addr, &socket); 126 T_ASSERT_POSIX_FAILURE(result, EADDRNOTAVAIL, "vsock do not bind to reserved cid"); 127 } 128 129 T_DECL(bind_host, "vsock do not bind to host cid") 130 { 131 int socket; 132 struct sockaddr_vm addr; 133 int result = vsock_bind(VMADDR_CID_HOST, VMADDR_PORT_ANY, &addr, &socket); 134 T_ASSERT_POSIX_FAILURE(result, EADDRNOTAVAIL, "vsock do not bind to host cid"); 135 } 136 137 T_DECL(bind_zero, "vsock bind to port zero", T_META_ASROOT(true)) 138 { 139 const uint32_t port = 0; 140 141 int socket; 142 struct sockaddr_vm addr; 143 int result = vsock_bind(VMADDR_CID_ANY, port, &addr, &socket); 144 T_ASSERT_POSIX_SUCCESS(result, "vsock bind to port zero"); 145 146 struct sockaddr_vm bound_addr; 147 socklen_t length = sizeof(struct sockaddr_vm); 148 result = getsockname(socket, (struct sockaddr *)&bound_addr, &length); 149 T_ASSERT_POSIX_SUCCESS(result, "vsock getsockname"); 150 T_ASSERT_EQ_INT((int) sizeof(bound_addr), length, "correct address length"); 151 T_ASSERT_EQ_UINT(bound_addr.svm_port, port, "bound to local port zero"); 152 } 153 154 T_DECL(bind_double, "vsock double bind") 155 { 156 const uint32_t cid = VMADDR_CID_ANY; 157 const uint32_t port = vsock_get_available_port(); 158 159 int socket; 160 struct sockaddr_vm addr; 161 int result = vsock_bind(cid, port, &addr, &socket); 162 T_ASSERT_POSIX_SUCCESS(result, "vsock bind to a port"); 163 164 result = bind(socket, (struct sockaddr *) &addr, sizeof(addr)); 165 T_ASSERT_POSIX_FAILURE(result, EINVAL, "vsock bind to same port"); 166 } 167 168 T_DECL(bind_same, "vsock bind same address and port") 169 { 170 const uint32_t cid = VMADDR_CID_ANY; 171 const uint32_t port = vsock_get_available_port(); 172 173 int socket; 174 struct sockaddr_vm addr; 175 int result = vsock_bind(cid, port, &addr, &socket); 176 T_ASSERT_POSIX_SUCCESS(result, "vsock bind to a port"); 177 178 result = vsock_bind(cid, port, &addr, &socket); 179 T_ASSERT_POSIX_FAILURE(result, EADDRINUSE, "vsock bind to same address and port"); 180 } 181 182 T_DECL(bind_port_reuse, "vsock bind port reuse") 183 { 184 const uint32_t cid = VMADDR_CID_ANY; 185 const uint32_t port = vsock_get_available_port(); 186 187 int socket; 188 struct sockaddr_vm addr; 189 int result = vsock_bind(cid, port, &addr, &socket); 190 T_ASSERT_POSIX_SUCCESS(result, "vsock bind to a port"); 191 192 vsock_close(socket); 193 194 result = vsock_bind(cid, port, &addr, &socket); 195 T_ASSERT_POSIX_SUCCESS(result, "vsock bind to a port"); 196 } 197 198 T_DECL(bind_privileged_non_root, "vsock bind on privileged port - non-root", T_META_ASROOT(false)) 199 { 200 if (geteuid() == 0) { 201 T_SKIP("test requires non-root privileges to run."); 202 } 203 struct sockaddr_vm addr; 204 int socket; 205 int result = vsock_bind(VMADDR_CID_ANY, 5, &addr, &socket); 206 T_ASSERT_POSIX_FAILURE(result, EACCES, "vsock bind privileged as non-root"); 207 } 208 209 T_DECL(bind_privileged_root, "vsock bind on privileged port - root", T_META_ASROOT(true)) 210 { 211 if (geteuid() != 0) { 212 T_SKIP("test requires root privileges to run."); 213 } 214 struct sockaddr_vm addr; 215 int socket; 216 int result = vsock_bind(VMADDR_CID_ANY, 6, &addr, &socket); 217 T_ASSERT_POSIX_SUCCESS(result, "vsock bind privileged as root"); 218 } 219 220 T_DECL(bind_no_family, "vsock bind with unspecified family") 221 { 222 int result = vsock_bind_family(AF_UNSPEC); 223 T_ASSERT_POSIX_SUCCESS(result, "vsock bind with unspecified family"); 224 } 225 226 T_DECL(bind_vsock_family, "vsock bind with vsock family") 227 { 228 int result = vsock_bind_family(AF_VSOCK); 229 T_ASSERT_POSIX_SUCCESS(result, "vsock bind with vsock family"); 230 } 231 232 T_DECL(bind_wrong_family, "vsock bind with wrong family") 233 { 234 int result = vsock_bind_family(AF_INET); 235 T_ASSERT_POSIX_FAILURE(result, EAFNOSUPPORT, "vsock bind with wrong family"); 236 } 237 238 /* Listen */ 239 240 T_DECL(listen, "vsock listen on specific port") 241 { 242 struct sockaddr_vm addr; 243 int socket; 244 const uint32_t port = vsock_get_available_port(); 245 int result = vsock_listen(VMADDR_CID_ANY, port, &addr, 10, &socket); 246 T_ASSERT_POSIX_SUCCESS(result, "vsock listen"); 247 } 248 249 T_DECL(listen_any, "vsock listen on any port") 250 { 251 struct sockaddr_vm addr; 252 int socket; 253 int result = vsock_listen(VMADDR_CID_ANY, VMADDR_PORT_ANY, &addr, 10, &socket); 254 T_ASSERT_POSIX_SUCCESS(result, "vsock listen"); 255 } 256 257 /* Connect */ 258 259 T_DECL(connect_non_hypervisor, "vsock connect to remote other than hypervisor") 260 { 261 int socket; 262 int result = vsock_connect(5555, 1234, &socket); 263 T_ASSERT_POSIX_FAILURE(result, EFAULT, "vsock connect non-hypervisor"); 264 } 265 266 T_DECL(connect_non_listening_host, "vsock connect to non-listening host port") 267 { 268 int socket; 269 int result = vsock_connect(VMADDR_CID_HOST, 7777, &socket); 270 T_ASSERT_POSIX_FAILURE(result, EAGAIN, "vsock connect non-listening host port"); 271 } 272 273 T_DECL(connect_non_listening_hypervisor, "vsock connect to non-listening hypervisor port") 274 { 275 int socket; 276 int result = vsock_connect(VMADDR_CID_HYPERVISOR, 4444, &socket); 277 T_ASSERT_POSIX_FAILURE(result, EAGAIN, "vsock connect non-listening hypervisor port"); 278 } 279 280 T_DECL(connect_getsockname, "vsock connect - getsockname") 281 { 282 int socket; 283 int result = vsock_connect(VMADDR_CID_HOST, 9999, &socket); 284 T_ASSERT_POSIX_FAILURE(result, EAGAIN, "vsock connect non-listening"); 285 286 vsock_getsockname(socket); 287 } 288 289 T_DECL(connect_timeout, "vsock connect with timeout") 290 { 291 int socket = vsock_new_socket(); 292 293 struct timeval timeout = (struct timeval) { 294 .tv_sec = 0, 295 .tv_usec = 1, 296 }; 297 int result = setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); 298 T_ASSERT_POSIX_SUCCESS(result, "vsock set socket timeout"); 299 300 const uint32_t port = vsock_get_available_port(); 301 struct sockaddr_vm addr = (struct sockaddr_vm) { 302 .svm_cid = VMADDR_CID_HOST, 303 .svm_port = port, 304 }; 305 result = connect(socket, (struct sockaddr *)&addr, sizeof(addr)); 306 T_ASSERT_POSIX_FAILURE(result, ETIMEDOUT, "vsock connect timeout"); 307 } 308 309 T_DECL(connect_non_blocking, "vsock connect non-blocking") 310 { 311 int socket = vsock_new_socket(); 312 313 const uint32_t port = vsock_get_available_port(); 314 const uint32_t cid = vsock_get_local_cid(socket); 315 316 // Listen. 317 struct sockaddr_vm listen_addr; 318 int listen_socket; 319 long result = vsock_listen(cid, port, &listen_addr, 10, &listen_socket); 320 T_ASSERT_POSIX_SUCCESS(result, "vsock listen"); 321 322 // Set non-blocking. 323 long arg = fcntl(socket, F_GETFL, NULL); 324 T_ASSERT_GT(arg, -1L, "vsock get args"); 325 arg |= O_NONBLOCK; 326 result = fcntl(socket, F_SETFL, arg); 327 T_ASSERT_GT(arg, -1L, "vsock set args"); 328 329 // Connect. 330 struct sockaddr_vm addr = (struct sockaddr_vm) { 331 .svm_cid = cid, 332 .svm_port = port, 333 }; 334 result = connect(socket, (struct sockaddr *)&addr, sizeof(addr)); 335 if (result != 0 && errno != EINPROGRESS) { 336 T_ASSERT_FAIL("vsock connect should succeed or return EINPROGRESS. errno: %u", errno); 337 } 338 339 vsock_close(socket); 340 vsock_close(listen_socket); 341 } 342 343 /* Shutdown */ 344 345 T_DECL(shutdown_not_connected, "vsock shutdown - not connected") 346 { 347 int how[] = {SHUT_RD, SHUT_WR, SHUT_RDWR}; 348 for (unsigned long i = 0; i < COUNT_ELEMS(how); i++) { 349 int socket = vsock_new_socket(); 350 int result = shutdown(socket, how[i]); 351 T_ASSERT_POSIX_FAILURE(result, ENOTCONN, "vsock cannot shutdown"); 352 } 353 } 354 355 T_DECL(shutdown_reads, "vsock shutdown - reads") 356 { 357 int socketA, socketB; 358 const uint32_t port = vsock_get_available_port(); 359 vsock_connect_peers(VMADDR_CID_ANY, port, 10, &socketA, &socketB); 360 361 char *msg = "This is test message.\n"; 362 363 // 'A' sends a message. 364 vsock_send(socketA, msg); 365 366 // 'B' shutsdown reads. 367 int result = shutdown(socketB, SHUT_RD); 368 T_ASSERT_POSIX_SUCCESS(result, "vsock shutdown reads"); 369 370 // 'B' reads nothing. 371 char buffer[1024] = {0}; 372 ssize_t read_bytes = read(socketB, buffer, 1024); 373 T_ASSERT_EQ_LONG(0L, read_bytes, "read zero bytes"); 374 375 // 'B' can still send. 376 vsock_send(socketB, msg); 377 378 vsock_close(socketA); 379 vsock_close(socketB); 380 } 381 382 T_DECL(shutdown_writes, "vsock shutdown - writes") 383 { 384 int socketA, socketB; 385 const uint32_t port = vsock_get_available_port(); 386 vsock_connect_peers(VMADDR_CID_ANY, port, 10, &socketA, &socketB); 387 388 char *msg = "This is test message.\n"; 389 390 // 'A' sends a message. 391 vsock_send(socketA, msg); 392 393 // 'B' sends a message. 394 vsock_send(socketB, msg); 395 396 // send() hits us with a SIGPIPE if peer closes. ignore this and catch the error code. 397 vsock_disable_sigpipe(socketB); 398 399 // 'B' shutsdown writes. 400 int result = shutdown(socketB, SHUT_WR); 401 T_ASSERT_POSIX_SUCCESS(result, "vsock shutdown writes"); 402 403 // 'B' fails to write. 404 ssize_t sent_bytes = send(socketB, msg, strlen(msg), 0); 405 T_ASSERT_POSIX_FAILURE(sent_bytes, EPIPE, "vsock cannot write"); 406 407 // 'B' can still read. 408 char buffer[1024] = {0}; 409 ssize_t read_bytes = read(socketB, buffer, 1024); 410 T_ASSERT_EQ_LONG(strlen(msg), (unsigned long)read_bytes, "read all bytes"); 411 412 vsock_close(socketA); 413 vsock_close(socketB); 414 } 415 416 T_DECL(shutdown_both, "vsock shutdown - both") 417 { 418 int socketA, socketB; 419 const uint32_t port = vsock_get_available_port(); 420 vsock_connect_peers(VMADDR_CID_ANY, port, 10, &socketA, &socketB); 421 422 char *msg = "This is test message.\n"; 423 char buffer[1024] = {0}; 424 425 // 'A' sends a message. 426 vsock_send(socketA, msg); 427 428 // 'B' sends a message. 429 vsock_send(socketB, msg); 430 431 // 'B' reads a message. 432 ssize_t read_bytes = read(socketB, buffer, 1024); 433 T_ASSERT_EQ_LONG(strlen(msg), (unsigned long)read_bytes, "read all bytes"); 434 T_ASSERT_EQ_STR(msg, buffer, "same message"); 435 436 // 'A' sends a message. 437 vsock_send(socketA, msg); 438 439 // send() hits us with a SIGPIPE if peer closes. ignore this and catch the error code. 440 vsock_disable_sigpipe(socketB); 441 442 // 'B' shutsdown reads and writes. 443 int result = shutdown(socketB, SHUT_RDWR); 444 T_ASSERT_POSIX_SUCCESS(result, "vsock shutdown reads and writes"); 445 446 // 'B' fails to write. 447 ssize_t sent_bytes = send(socketB, msg, strlen(msg), 0); 448 T_ASSERT_POSIX_FAILURE(sent_bytes, EPIPE, "vsock cannot write"); 449 450 // 'B' reads nothing. 451 read_bytes = read(socketB, buffer, 1024); 452 T_ASSERT_EQ_LONG(0L, read_bytes, "read zero bytes"); 453 454 vsock_close(socketA); 455 vsock_close(socketB); 456 } 457 458 /* Communication */ 459 460 T_DECL(talk_self, "vsock talk to self") 461 { 462 int socketA, socketB; 463 const uint32_t port = vsock_get_available_port(); 464 vsock_connect_peers(VMADDR_CID_ANY, port, 10, &socketA, &socketB); 465 466 char buffer[1024] = {0}; 467 468 for (int i = 0; i < 64; i++) { 469 // Send a message. 470 char *msg = (char*)malloc(64 * sizeof(char)); 471 sprintf(msg, "This is test message %d\n", i); 472 vsock_send(socketA, msg); 473 474 // Receive a message. 475 ssize_t read_bytes = read(socketB, buffer, 1024); 476 T_ASSERT_EQ_LONG(strlen(msg), (unsigned long)read_bytes, "read all bytes"); 477 T_ASSERT_EQ_STR(msg, buffer, "same message"); 478 free(msg); 479 } 480 481 vsock_close(socketA); 482 vsock_close(socketB); 483 } 484 485 T_DECL(talk_self_double, "vsock talk to self - double sends") 486 { 487 int socketA, socketB; 488 const uint32_t port = vsock_get_available_port(); 489 vsock_connect_peers(VMADDR_CID_ANY, port, 10, &socketA, &socketB); 490 491 char buffer[1024] = {0}; 492 493 for (int i = 0; i < 64; i++) { 494 // Send a message. 495 char *msg = (char*)malloc(64 * sizeof(char)); 496 sprintf(msg, "This is test message %d\n", i); 497 vsock_send(socketA, msg); 498 499 // Send the same message. 500 vsock_send(socketA, msg); 501 502 // Receive a message. 503 ssize_t read_bytes = read(socketB, buffer, 1024); 504 T_ASSERT_EQ_LONG(strlen(msg) * 2, (unsigned long)read_bytes, "read all bytes"); 505 char *expected_msg = (char*)malloc(64 * sizeof(char)); 506 sprintf(expected_msg, "%s%s", msg, msg); 507 T_ASSERT_EQ_STR(expected_msg, buffer, "same message"); 508 free(msg); 509 free(expected_msg); 510 } 511 512 vsock_close(socketA); 513 vsock_close(socketB); 514 } 515 516 T_DECL(talk_self_early_close, "vsock talk to self - peer closes early") 517 { 518 int socketA, socketB; 519 const uint32_t port = vsock_get_available_port(); 520 vsock_connect_peers(VMADDR_CID_ANY, port, 10, &socketA, &socketB); 521 522 char *msg = "This is a message."; 523 vsock_send(socketA, msg); 524 525 // send() hits us with a SIGPIPE if peer closes. ignore this and catch the error code. 526 vsock_disable_sigpipe(socketA); 527 528 vsock_close(socketB); 529 530 ssize_t result = send(socketA, msg, strlen(msg), 0); 531 T_ASSERT_POSIX_FAILURE(result, EPIPE, "vsock peer closed"); 532 533 vsock_close(socketA); 534 } 535 536 T_DECL(talk_self_connections, "vsock talk to self - too many connections") 537 { 538 const uint32_t port = vsock_get_available_port(); 539 const int backlog = 1; 540 541 struct sockaddr_vm listen_addr; 542 int listen_socket; 543 int result = vsock_listen(VMADDR_CID_ANY, port, &listen_addr, backlog, &listen_socket); 544 T_ASSERT_POSIX_SUCCESS(result, "vsock listen"); 545 546 const uint32_t connection_cid = vsock_get_local_cid(listen_socket); 547 548 // One backlog. 549 int connected_socket = vsock_new_socket(); 550 struct sockaddr_vm addr = (struct sockaddr_vm) { 551 .svm_cid = connection_cid, 552 .svm_port = port, 553 }; 554 result = connect(connected_socket, (struct sockaddr *)&addr, sizeof(addr)); 555 T_ASSERT_POSIX_SUCCESS(result, "vsock connection successful"); 556 557 int bad_socket = vsock_new_socket(); 558 result = connect(bad_socket, (struct sockaddr *)&addr, sizeof(addr)); 559 T_ASSERT_POSIX_FAILURE(result, ECONNREFUSED, "vsock connection refused"); 560 561 vsock_close(connected_socket); 562 vsock_close(listen_socket); 563 } 564 565 // rdar://84098487 (SEED: Web: Virtio-socket sent data lost after 128KB) 566 T_DECL(talk_self_large_writes, "vsock talk to self with large writes") 567 { 568 int socketA, socketB; 569 const uint32_t port = vsock_get_available_port(); 570 vsock_connect_peers(VMADDR_CID_ANY, port, 10, &socketA, &socketB); 571 572 size_t size = 65536 * 4; 573 char buffer[65536 * 4] = {0}; 574 void *random = malloc(size); 575 576 for (int i = 0; i < 64; i++) { 577 // Send a message. 578 ssize_t sent = write(socketA, random, size); 579 T_ASSERT_EQ_LONG(size, sent, "sent all bytes"); 580 581 // Receive a message. 582 ssize_t read_bytes = read(socketB, buffer, size); 583 T_ASSERT_EQ_LONG(size, (unsigned long)read_bytes, "read all bytes"); 584 585 // Sent and received same data. 586 T_ASSERT_EQ_INT(0, memcmp(random, buffer, size), "sent and received same data"); 587 } 588 589 free(random); 590 vsock_close(socketA); 591 vsock_close(socketB); 592 } 593 594 /* Sysctl */ 595 596 static const char* pcblist = "net.vsock.pcblist"; 597 598 T_DECL(vsock_pcblist_simple, "vsock pcblist sysctl - simple") 599 { 600 // Create some socket to discover in the pcblist. 601 struct sockaddr_vm addr; 602 int socket; 603 const uint32_t port = vsock_get_available_port(); 604 int result = vsock_listen(VMADDR_CID_ANY, port, &addr, 10, &socket); 605 T_ASSERT_POSIX_SUCCESS(result, "vsock listen on a port"); 606 607 // Get the buffer length for the pcblist. 608 size_t length = 0; 609 result = sysctlbyname(pcblist, 0, &length, 0, 0); 610 if (result == ENOENT) { 611 T_SKIP("%s missing", pcblist); 612 } 613 T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist get buffer size (result %d)", result); 614 615 // Allocate the buffer. 616 struct xvsockpgen *buffer = malloc(length); 617 T_ASSERT_NOTNULL(buffer, "allocated buffer is not null"); 618 619 // Populate the buffer with the pcblist. 620 result = sysctlbyname(pcblist, buffer, &length, 0, 0); 621 T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist populate buffer"); 622 623 // The socket should exist in the list. 624 bool exists = vsock_address_exists(buffer, addr); 625 T_ASSERT_TRUE(exists, "vsock pcblist contains the specified socket"); 626 627 vsock_close(socket); 628 free(buffer); 629 } 630 631 T_DECL(vsock_pcblist_added, "vsock pcblist sysctl - socket added") 632 { 633 // Get the buffer length for the pcblist. 634 size_t length = 0; 635 int result = sysctlbyname(pcblist, 0, &length, 0, 0); 636 if (result == ENOENT) { 637 T_SKIP("%s missing", pcblist); 638 } 639 T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist get buffer size (result %d)", result); 640 641 // Create some socket to discover in the pcblist after making the first sysctl. 642 struct sockaddr_vm addr; 643 int socket; 644 const uint32_t port = vsock_get_available_port(); 645 result = vsock_listen(VMADDR_CID_ANY, port, &addr, 10, &socket); 646 T_ASSERT_POSIX_SUCCESS(result, "vsock listen on a port"); 647 648 // Allocate the buffer. 649 struct xvsockpgen *buffer = malloc(length); 650 T_ASSERT_NOTNULL(buffer, "allocated buffer is not null"); 651 652 // Populate the buffer with the pcblist. 653 result = sysctlbyname(pcblist, buffer, &length, 0, 0); 654 T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist populate buffer"); 655 656 // The socket was created after the buffer and cannot fit. 657 bool exists = vsock_address_exists(buffer, addr); 658 T_ASSERT_FALSE(exists, "vsock pcblist should not contain the new socket"); 659 660 vsock_close(socket); 661 free(buffer); 662 } 663 664 T_DECL(vsock_pcblist_removed, "vsock pcblist sysctl - socket removed") 665 { 666 // Create some socket to be removed after making the first sysctl. 667 struct sockaddr_vm addr; 668 int socket; 669 const uint32_t port = vsock_get_available_port(); 670 int result = vsock_listen(VMADDR_CID_ANY, port, &addr, 10, &socket); 671 T_ASSERT_POSIX_SUCCESS(result, "vsock listen on a port"); 672 673 // Get the buffer length for the pcblist. 674 size_t length = 0; 675 result = sysctlbyname(pcblist, 0, &length, 0, 0); 676 if (result == ENOENT) { 677 T_SKIP("%s missing", pcblist); 678 } 679 T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist get buffer size (result %d)", result); 680 681 // Close the socket early. 682 vsock_close(socket); 683 684 // Allocate the buffer. 685 struct xvsockpgen *buffer = malloc(length); 686 T_ASSERT_NOTNULL(buffer, "allocated buffer is not null"); 687 688 // Populate the buffer with the pcblist. 689 result = sysctlbyname(pcblist, buffer, &length, 0, 0); 690 T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist populate buffer"); 691 692 // The socket was destroyed before populating the list and should not exist. 693 bool exists = vsock_address_exists(buffer, addr); 694 T_ASSERT_FALSE(exists, "vsock pcblist should not contain the deleted socket"); 695 696 free(buffer); 697 } 698 699 T_DECL(vsock_private_connect_without_entitlement, "vsock private connect should fail without entitlement") 700 { 701 int socket; 702 int result = vsock_private_connect(VMADDR_CID_HOST, 1234, &socket); 703 T_ASSERT_POSIX_FAILURE(result, EPERM, "vsock connect without entitlement"); 704 } 705 706 T_DECL(vsock_private_bind_without_entitlement, "vsock private bind should fail without entitlement") 707 { 708 int socket; 709 struct sockaddr_vm addr; 710 int result = vsock_private_bind(VMADDR_CID_ANY, 1234, &addr, &socket); 711 T_ASSERT_POSIX_FAILURE(result, EPERM, "vsock bind without entitlement"); 712 } 713