1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2024 Stormshield 5 */ 6 7 #include <sys/capsicum.h> 8 #include <sys/event.h> 9 #include <sys/filio.h> 10 #include <sys/socket.h> 11 #include <sys/wait.h> 12 13 #include <netinet/in.h> 14 #include <netinet/tcp.h> 15 16 #include <errno.h> 17 #include <poll.h> 18 #include <pthread.h> 19 #include <signal.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 #include <time.h> 24 25 #include <atf-c.h> 26 27 static void 28 checked_close(int fd) 29 { 30 int error; 31 32 error = close(fd); 33 ATF_REQUIRE_MSG(error == 0, "close failed: %s", strerror(errno)); 34 } 35 36 static int 37 fionread(int fd) 38 { 39 int data, error; 40 41 data = 0; 42 error = ioctl(fd, FIONREAD, &data); 43 ATF_REQUIRE_MSG(error == 0, "ioctl failed: %s", strerror(errno)); 44 ATF_REQUIRE(data >= 0); 45 return (data); 46 } 47 48 static void 49 noblocking(int fd) 50 { 51 int flags, error; 52 53 flags = fcntl(fd, F_GETFL); 54 ATF_REQUIRE_MSG(flags != -1, "fcntl failed: %s", strerror(errno)); 55 flags |= O_NONBLOCK; 56 error = fcntl(fd, F_SETFL, flags); 57 ATF_REQUIRE_MSG(error == 0, "fcntl failed: %s", strerror(errno)); 58 } 59 60 /* 61 * Create a pair of connected TCP sockets, returned via the "out" array. 62 */ 63 static void 64 tcp_socketpair(int out[2], int domain) 65 { 66 struct sockaddr_in sin; 67 struct sockaddr_in6 sin6; 68 struct sockaddr *sinp; 69 int error, sd[2]; 70 71 sd[0] = socket(domain, SOCK_STREAM, 0); 72 ATF_REQUIRE_MSG(sd[0] >= 0, "socket failed: %s", strerror(errno)); 73 sd[1] = socket(domain, SOCK_STREAM, 0); 74 ATF_REQUIRE_MSG(sd[1] >= 0, "socket failed: %s", strerror(errno)); 75 76 error = setsockopt(sd[0], IPPROTO_TCP, TCP_NODELAY, &(int){ 1 }, 77 sizeof(int)); 78 ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno)); 79 error = setsockopt(sd[1], IPPROTO_TCP, TCP_NODELAY, &(int){ 1 }, 80 sizeof(int)); 81 ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno)); 82 83 if (domain == PF_INET) { 84 memset(&sin, 0, sizeof(sin)); 85 sin.sin_family = AF_INET; 86 sin.sin_len = sizeof(sin); 87 sin.sin_addr.s_addr = htonl(INADDR_ANY); 88 sin.sin_port = htons(0); 89 sinp = (struct sockaddr *)&sin; 90 } else { 91 ATF_REQUIRE(domain == PF_INET6); 92 memset(&sin6, 0, sizeof(sin6)); 93 sin6.sin6_family = AF_INET6; 94 sin6.sin6_len = sizeof(sin6); 95 sin6.sin6_addr = in6addr_any; 96 sin6.sin6_port = htons(0); 97 sinp = (struct sockaddr *)&sin6; 98 } 99 100 error = bind(sd[0], sinp, sinp->sa_len); 101 ATF_REQUIRE_MSG(error == 0, "bind failed: %s", strerror(errno)); 102 error = listen(sd[0], 1); 103 ATF_REQUIRE_MSG(error == 0, "listen failed: %s", strerror(errno)); 104 105 error = getsockname(sd[0], sinp, &(socklen_t){ sinp->sa_len }); 106 ATF_REQUIRE_MSG(error == 0, "getsockname failed: %s", strerror(errno)); 107 108 error = connect(sd[1], sinp, sinp->sa_len); 109 ATF_REQUIRE_MSG(error == 0, "connect failed: %s", strerror(errno)); 110 out[0] = accept(sd[0], NULL, NULL); 111 ATF_REQUIRE_MSG(out[0] >= 0, "accept failed: %s", strerror(errno)); 112 checked_close(sd[0]); 113 out[1] = sd[1]; 114 } 115 116 static void 117 tcp4_socketpair(int out[2]) 118 { 119 tcp_socketpair(out, PF_INET); 120 } 121 122 static void 123 tcp6_socketpair(int out[2]) 124 { 125 tcp_socketpair(out, PF_INET6); 126 } 127 128 static off_t 129 nspliced(int sd) 130 { 131 off_t n; 132 socklen_t len; 133 int error; 134 135 len = sizeof(n); 136 error = getsockopt(sd, SOL_SOCKET, SO_SPLICE, &n, &len); 137 ATF_REQUIRE_MSG(error == 0, "getsockopt failed: %s", strerror(errno)); 138 ATF_REQUIRE_MSG(len == sizeof(n), "unexpected length: %d", len); 139 return (n); 140 } 141 142 /* 143 * Use a macro so that ATF_REQUIRE_MSG prints a useful line number. 144 */ 145 #define check_nspliced(sd, n) do { \ 146 off_t sofar; \ 147 \ 148 sofar = nspliced(sd); \ 149 ATF_REQUIRE_MSG(sofar == (off_t)n, "spliced %jd bytes, expected %jd", \ 150 (intmax_t)sofar, (intmax_t)n); \ 151 } while (0) 152 153 static void 154 splice_init(struct splice *sp, int fd, off_t max, struct timeval *tv) 155 { 156 memset(sp, 0, sizeof(*sp)); 157 sp->sp_fd = fd; 158 sp->sp_max = max; 159 if (tv != NULL) 160 sp->sp_idle = *tv; 161 else 162 sp->sp_idle.tv_sec = sp->sp_idle.tv_usec = 0; 163 } 164 165 static void 166 unsplice(int fd) 167 { 168 struct splice sp; 169 int error; 170 171 splice_init(&sp, -1, 0, NULL); 172 error = setsockopt(fd, SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 173 ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno)); 174 } 175 176 static void 177 unsplice_pair(int fd1, int fd2) 178 { 179 unsplice(fd1); 180 unsplice(fd2); 181 } 182 183 static void 184 splice_pair(int fd1, int fd2, off_t max, struct timeval *tv) 185 { 186 struct splice sp; 187 int error; 188 189 splice_init(&sp, fd1, max, tv); 190 error = setsockopt(fd2, SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 191 ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno)); 192 193 splice_init(&sp, fd2, max, tv); 194 error = setsockopt(fd1, SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 195 ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno)); 196 } 197 198 /* 199 * A structure representing a spliced pair of connections. left[1] is 200 * bidirectionally spliced with right[0]. 201 */ 202 struct splice_conn { 203 int left[2]; 204 int right[2]; 205 }; 206 207 /* 208 * Initialize a splice connection with the given maximum number of bytes to 209 * splice and the given idle timeout. For now we're forced to use TCP socket, 210 * but at some point it would be nice (and simpler) to use pairs of PF_LOCAL 211 * sockets. 212 */ 213 static void 214 splice_conn_init_limits(struct splice_conn *sc, off_t max, struct timeval *tv) 215 { 216 memset(sc, 0, sizeof(*sc)); 217 tcp4_socketpair(sc->left); 218 tcp4_socketpair(sc->right); 219 splice_pair(sc->left[1], sc->right[0], max, tv); 220 } 221 222 static void 223 splice_conn_init(struct splice_conn *sc) 224 { 225 splice_conn_init_limits(sc, 0, NULL); 226 } 227 228 static void 229 splice_conn_check_empty(struct splice_conn *sc) 230 { 231 int data; 232 233 data = fionread(sc->left[0]); 234 ATF_REQUIRE_MSG(data == 0, "unexpected data on left[0]: %d", data); 235 data = fionread(sc->left[1]); 236 ATF_REQUIRE_MSG(data == 0, "unexpected data on left[1]: %d", data); 237 data = fionread(sc->right[0]); 238 ATF_REQUIRE_MSG(data == 0, "unexpected data on right[0]: %d", data); 239 data = fionread(sc->right[1]); 240 ATF_REQUIRE_MSG(data == 0, "unexpected data on right[1]: %d", data); 241 } 242 243 static void 244 splice_conn_fini(struct splice_conn *sc) 245 { 246 checked_close(sc->left[0]); 247 checked_close(sc->left[1]); 248 checked_close(sc->right[0]); 249 checked_close(sc->right[1]); 250 } 251 252 static void 253 splice_conn_noblocking(struct splice_conn *sc) 254 { 255 noblocking(sc->left[0]); 256 noblocking(sc->left[1]); 257 noblocking(sc->right[0]); 258 noblocking(sc->right[1]); 259 } 260 261 /* Pass a byte through a pair of spliced connections. */ 262 ATF_TC_WITHOUT_HEAD(splice_basic); 263 ATF_TC_BODY(splice_basic, tc) 264 { 265 struct splice_conn sc; 266 ssize_t n; 267 char c; 268 269 splice_conn_init(&sc); 270 271 check_nspliced(sc.left[1], 0); 272 check_nspliced(sc.right[0], 0); 273 274 /* Left-to-right. */ 275 c = 'M'; 276 n = write(sc.left[0], &c, 1); 277 ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno)); 278 n = read(sc.right[1], &c, 1); 279 ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno)); 280 ATF_REQUIRE_MSG(c == 'M', "unexpected character: %c", c); 281 check_nspliced(sc.left[1], 1); 282 check_nspliced(sc.right[0], 0); 283 284 /* Right-to-left. */ 285 c = 'J'; 286 n = write(sc.right[1], &c, 1); 287 ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno)); 288 n = read(sc.left[0], &c, 1); 289 ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno)); 290 ATF_REQUIRE_MSG(c == 'J', "unexpected character: %c", c); 291 check_nspliced(sc.left[1], 1); 292 check_nspliced(sc.right[0], 1); 293 294 /* Unsplice and verify that the byte counts haven't changed. */ 295 unsplice(sc.left[1]); 296 unsplice(sc.right[0]); 297 check_nspliced(sc.left[1], 1); 298 check_nspliced(sc.right[0], 1); 299 300 splice_conn_fini(&sc); 301 } 302 303 static void 304 remove_rights(int fd, const cap_rights_t *toremove) 305 { 306 cap_rights_t rights; 307 int error; 308 309 error = cap_rights_get(fd, &rights); 310 ATF_REQUIRE_MSG(error == 0, "cap_rights_get failed: %s", 311 strerror(errno)); 312 cap_rights_remove(&rights, toremove); 313 error = cap_rights_limit(fd, &rights); 314 ATF_REQUIRE_MSG(error == 0, "cap_rights_limit failed: %s", 315 strerror(errno)); 316 } 317 318 /* 319 * Verify that splicing fails when the socket is missing the necessary rights. 320 */ 321 ATF_TC_WITHOUT_HEAD(splice_capsicum); 322 ATF_TC_BODY(splice_capsicum, tc) 323 { 324 struct splice sp; 325 cap_rights_t rights; 326 off_t n; 327 int error, left[2], right[2]; 328 329 tcp4_socketpair(left); 330 tcp4_socketpair(right); 331 332 /* 333 * Make sure that we splice a socket that's missing recv rights. 334 */ 335 remove_rights(left[1], cap_rights_init(&rights, CAP_RECV)); 336 splice_init(&sp, right[0], 0, NULL); 337 error = setsockopt(left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 338 ATF_REQUIRE_ERRNO(ENOTCAPABLE, error == -1); 339 340 /* Make sure we can still splice left[1] in the other direction. */ 341 splice_init(&sp, left[1], 0, NULL); 342 error = setsockopt(right[0], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 343 ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno)); 344 splice_init(&sp, -1, 0, NULL); 345 error = setsockopt(right[0], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 346 ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno)); 347 348 /* 349 * Now remove send rights from left[1] and verify that splicing is no 350 * longer possible. 351 */ 352 remove_rights(left[1], cap_rights_init(&rights, CAP_SEND)); 353 splice_init(&sp, left[1], 0, NULL); 354 error = setsockopt(right[0], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 355 ATF_REQUIRE_ERRNO(ENOTCAPABLE, error == -1); 356 357 /* 358 * It's still ok to query the SO_SPLICE state though. 359 */ 360 n = -1; 361 error = getsockopt(left[1], SOL_SOCKET, SO_SPLICE, &n, 362 &(socklen_t){ sizeof(n) }); 363 ATF_REQUIRE_MSG(error == 0, "getsockopt failed: %s", strerror(errno)); 364 ATF_REQUIRE(n == 0); 365 366 /* 367 * Make sure that we can unsplice a spliced pair without any rights 368 * other than CAP_SETSOCKOPT. 369 */ 370 splice_pair(left[0], right[1], 0, NULL); 371 error = cap_rights_limit(left[0], 372 cap_rights_init(&rights, CAP_SETSOCKOPT)); 373 ATF_REQUIRE_MSG(error == 0, "cap_rights_limit failed: %s", 374 strerror(errno)); 375 unsplice(left[0]); 376 377 checked_close(left[0]); 378 checked_close(left[1]); 379 checked_close(right[0]); 380 checked_close(right[1]); 381 } 382 383 /* 384 * Check various error cases in splice configuration. 385 */ 386 ATF_TC_WITHOUT_HEAD(splice_error); 387 ATF_TC_BODY(splice_error, tc) 388 { 389 struct splice_conn sc; 390 struct splice sp; 391 char path[PATH_MAX]; 392 int error, fd, sd, usd[2]; 393 394 memset(&sc, 0, sizeof(sc)); 395 tcp4_socketpair(sc.left); 396 tcp4_socketpair(sc.right); 397 398 /* A negative byte limit is invalid. */ 399 splice_init(&sp, sc.right[0], -3, NULL); 400 error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 401 ATF_REQUIRE_ERRNO(EINVAL, error == -1); 402 403 /* Can't unsplice a never-spliced socket. */ 404 splice_init(&sp, -1, 0, NULL); 405 error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 406 ATF_REQUIRE_ERRNO(ENOTCONN, error == -1); 407 408 /* Can't double-unsplice a socket. */ 409 splice_init(&sp, sc.right[0], 0, NULL); 410 error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 411 ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno)); 412 unsplice(sc.left[1]); 413 splice_init(&sp, -1, 0, NULL); 414 error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 415 ATF_REQUIRE_ERRNO(ENOTCONN, error == -1); 416 417 /* Can't splice a spliced socket */ 418 splice_init(&sp, sc.right[0], 0, NULL); 419 error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 420 ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno)); 421 splice_init(&sp, sc.right[1], 0, NULL); 422 error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 423 ATF_REQUIRE_ERRNO(EBUSY, error == -1); 424 splice_init(&sp, sc.right[0], 0, NULL); 425 error = setsockopt(sc.left[0], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 426 ATF_REQUIRE_ERRNO(EBUSY, error == -1); 427 splice_init(&sp, -1, 0, NULL); 428 error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 429 430 /* Can't splice to a non-socket. */ 431 snprintf(path, sizeof(path), "/tmp/splice_error.XXXXXX"); 432 fd = mkstemp(path); 433 ATF_REQUIRE_MSG(fd >= 0, "mkstemp failed: %s", strerror(errno)); 434 splice_init(&sp, fd, 0, NULL); 435 error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 436 ATF_REQUIRE_ERRNO(ENOTSOCK, error == -1); 437 438 /* Can't splice to an invalid fd. */ 439 checked_close(fd); 440 splice_init(&sp, fd, 0, NULL); 441 error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 442 ATF_REQUIRE_ERRNO(EBADF, error == -1); 443 444 /* Can't splice a unix stream socket. */ 445 error = socketpair(AF_UNIX, SOCK_STREAM, 0, usd); 446 ATF_REQUIRE_MSG(error == 0, "socketpair failed: %s", strerror(errno)); 447 splice_init(&sp, usd[0], 0, NULL); 448 error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 449 ATF_REQUIRE_ERRNO(EPROTONOSUPPORT, error == -1); 450 error = setsockopt(usd[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 451 ATF_REQUIRE_ERRNO(EPROTONOSUPPORT, error == -1); 452 checked_close(usd[0]); 453 checked_close(usd[1]); 454 455 /* Can't splice an unconnected TCP socket. */ 456 sd = socket(PF_INET, SOCK_STREAM, 0); 457 ATF_REQUIRE_MSG(sd >= 0, "socket failed: %s", strerror(errno)); 458 splice_init(&sp, sd, 0, NULL); 459 error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 460 ATF_REQUIRE_ERRNO(ENOTCONN, error == -1); 461 splice_init(&sp, sc.right[0], 0, NULL); 462 error = setsockopt(sd, SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 463 ATF_REQUIRE_ERRNO(ENOTCONN, error == -1); 464 465 splice_conn_fini(&sc); 466 } 467 468 /* 469 * Make sure that kevent() doesn't report read I/O events on spliced sockets. 470 */ 471 ATF_TC_WITHOUT_HEAD(splice_kevent); 472 ATF_TC_BODY(splice_kevent, tc) 473 { 474 struct splice_conn sc; 475 struct kevent kev; 476 struct timespec ts; 477 ssize_t n; 478 int error, nev, kq; 479 uint8_t b; 480 481 splice_conn_init(&sc); 482 483 kq = kqueue(); 484 ATF_REQUIRE_MSG(kq >= 0, "kqueue failed: %s", strerror(errno)); 485 486 EV_SET(&kev, sc.left[1], EVFILT_READ, EV_ADD, 0, 0, NULL); 487 error = kevent(kq, &kev, 1, NULL, 0, NULL); 488 ATF_REQUIRE_MSG(error == 0, "kevent failed: %s", strerror(errno)); 489 490 memset(&ts, 0, sizeof(ts)); 491 nev = kevent(kq, NULL, 0, &kev, 1, &ts); 492 ATF_REQUIRE_MSG(nev >= 0, "kevent failed: %s", strerror(errno)); 493 ATF_REQUIRE(nev == 0); 494 495 b = 'M'; 496 n = write(sc.left[0], &b, 1); 497 ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno)); 498 n = read(sc.right[1], &b, 1); 499 ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno)); 500 ATF_REQUIRE(b == 'M'); 501 502 nev = kevent(kq, NULL, 0, &kev, 1, &ts); 503 ATF_REQUIRE_MSG(nev >= 0, "kevent failed: %s", strerror(errno)); 504 ATF_REQUIRE(nev == 0); 505 506 b = 'J'; 507 n = write(sc.right[1], &b, 1); 508 ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno)); 509 n = read(sc.left[0], &b, 1); 510 ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno)); 511 ATF_REQUIRE(b == 'J'); 512 513 splice_conn_fini(&sc); 514 checked_close(kq); 515 } 516 517 /* 518 * Verify that a splice byte limit is applied. 519 */ 520 ATF_TC_WITHOUT_HEAD(splice_limit_bytes); 521 ATF_TC_BODY(splice_limit_bytes, tc) 522 { 523 struct splice_conn sc; 524 ssize_t n; 525 uint8_t b, buf[128]; 526 527 splice_conn_init_limits(&sc, sizeof(buf) + 1, NULL); 528 529 memset(buf, 'A', sizeof(buf)); 530 for (size_t total = sizeof(buf); total > 0; total -= n) { 531 n = write(sc.left[0], buf, total); 532 ATF_REQUIRE_MSG(n > 0, "write failed: %s", strerror(errno)); 533 } 534 for (size_t total = sizeof(buf); total > 0; total -= n) { 535 n = read(sc.right[1], buf, sizeof(buf)); 536 ATF_REQUIRE_MSG(n > 0, "read failed: %s", strerror(errno)); 537 } 538 539 check_nspliced(sc.left[1], sizeof(buf)); 540 check_nspliced(sc.right[0], 0); 541 542 /* Trigger an unsplice by writing the last byte. */ 543 b = 'B'; 544 n = write(sc.left[0], &b, 1); 545 ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno)); 546 n = read(sc.right[1], &b, 1); 547 ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno)); 548 ATF_REQUIRE(b == 'B'); 549 550 /* 551 * The next byte should appear on the other side of the connection 552 * rather than the splice. 553 */ 554 b = 'C'; 555 n = write(sc.left[0], &b, 1); 556 ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno)); 557 n = read(sc.left[1], &b, 1); 558 ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno)); 559 ATF_REQUIRE(b == 'C'); 560 561 splice_conn_check_empty(&sc); 562 563 splice_conn_fini(&sc); 564 } 565 566 /* 567 * Verify that a splice timeout limit is applied. 568 */ 569 ATF_TC_WITHOUT_HEAD(splice_limit_timeout); 570 ATF_TC_BODY(splice_limit_timeout, tc) 571 { 572 struct splice_conn sc; 573 ssize_t n; 574 int error; 575 uint8_t b, buf[128]; 576 577 splice_conn_init_limits(&sc, 0, 578 &(struct timeval){ .tv_sec = 0, .tv_usec = 500000 /* 500ms */ }); 579 580 /* Write some data through the splice. */ 581 memset(buf, 'A', sizeof(buf)); 582 for (size_t total = sizeof(buf); total > 0; total -= n) { 583 n = write(sc.left[0], buf, total); 584 ATF_REQUIRE_MSG(n > 0, "write failed: %s", strerror(errno)); 585 } 586 for (size_t total = sizeof(buf); total > 0; total -= n) { 587 n = read(sc.right[1], buf, sizeof(buf)); 588 ATF_REQUIRE_MSG(n > 0, "read failed: %s", strerror(errno)); 589 } 590 591 check_nspliced(sc.left[1], sizeof(buf)); 592 check_nspliced(sc.right[0], 0); 593 594 /* Wait for the splice to time out. */ 595 error = usleep(550000); 596 ATF_REQUIRE_MSG(error == 0, "usleep failed: %s", strerror(errno)); 597 598 /* 599 * The next byte should appear on the other side of the connection 600 * rather than the splice. 601 */ 602 b = 'C'; 603 n = write(sc.left[0], &b, 1); 604 ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno)); 605 n = read(sc.left[1], &b, 1); 606 ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno)); 607 ATF_REQUIRE(b == 'C'); 608 609 splice_conn_fini(&sc); 610 } 611 612 /* 613 * Make sure that listen() fails on spliced sockets, and that SO_SPLICE can't be 614 * used with listening sockets. 615 */ 616 ATF_TC_WITHOUT_HEAD(splice_listen); 617 ATF_TC_BODY(splice_listen, tc) 618 { 619 struct splice sp; 620 struct splice_conn sc; 621 int error, sd[3]; 622 623 /* 624 * These should fail regardless since the sockets are connected, but it 625 * doesn't hurt to check. 626 */ 627 splice_conn_init(&sc); 628 error = listen(sc.left[1], 1); 629 ATF_REQUIRE_ERRNO(EINVAL, error == -1); 630 error = listen(sc.right[0], 1); 631 ATF_REQUIRE_ERRNO(EINVAL, error == -1); 632 splice_conn_fini(&sc); 633 634 tcp4_socketpair(sd); 635 sd[2] = socket(PF_INET, SOCK_STREAM, 0); 636 ATF_REQUIRE_MSG(sd[2] >= 0, "socket failed: %s", strerror(errno)); 637 error = listen(sd[2], 1); 638 ATF_REQUIRE_MSG(error == 0, "listen failed: %s", strerror(errno)); 639 640 /* 641 * Make sure a listening socket can't be spliced in either direction. 642 */ 643 splice_init(&sp, sd[2], 0, NULL); 644 error = setsockopt(sd[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 645 ATF_REQUIRE_ERRNO(EINVAL, error == -1); 646 splice_init(&sp, sd[1], 0, NULL); 647 error = setsockopt(sd[2], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 648 ATF_REQUIRE_ERRNO(EINVAL, error == -1); 649 650 /* 651 * Make sure we can't try to unsplice a listening socket. 652 */ 653 splice_init(&sp, -1, 0, NULL); 654 error = setsockopt(sd[2], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 655 ATF_REQUIRE_ERRNO(EINVAL, error == -1); 656 657 checked_close(sd[0]); 658 checked_close(sd[1]); 659 checked_close(sd[2]); 660 } 661 662 static void 663 sigalarm(int sig __unused) 664 { 665 } 666 667 /* 668 * Our SO_SPLICE implementation doesn't do anything to prevent loops. We should 669 * however make sure that they are interruptible. 670 */ 671 ATF_TC_WITHOUT_HEAD(splice_loop); 672 ATF_TC_BODY(splice_loop, tc) 673 { 674 ssize_t n; 675 int sd[2], status; 676 pid_t child; 677 char c; 678 679 tcp_socketpair(sd, PF_INET); 680 splice_pair(sd[0], sd[1], 0, NULL); 681 682 /* 683 * Let the child process trigger an infinite loop. It should still be 684 * possible to kill the child with a signal, causing the connection to 685 * be dropped and ending the loop. 686 */ 687 child = fork(); 688 ATF_REQUIRE_MSG(child >= 0, "fork failed: %s", strerror(errno)); 689 if (child == 0) { 690 alarm(2); 691 c = 42; 692 n = write(sd[0], &c, 1); 693 if (n != 1) 694 _exit(2); 695 c = 24; 696 n = write(sd[1], &c, 1); 697 if (n != 1) 698 _exit(3); 699 700 for (;;) { 701 /* Wait for SIGALARM. */ 702 sleep(100); 703 } 704 705 _exit(0); 706 } else { 707 checked_close(sd[0]); 708 checked_close(sd[1]); 709 710 child = waitpid(child, &status, 0); 711 ATF_REQUIRE_MSG(child >= 0, 712 "waitpid failed: %s", strerror(errno)); 713 ATF_REQUIRE(WIFSIGNALED(status)); 714 ATF_REQUIRE(WTERMSIG(status) == SIGALRM); 715 } 716 } 717 718 /* 719 * Simple I/O test. 720 */ 721 ATF_TC_WITHOUT_HEAD(splice_nonblock); 722 ATF_TC_BODY(splice_nonblock, tc) 723 { 724 struct splice_conn sc; 725 char buf[200]; 726 size_t sofar; 727 ssize_t n; 728 729 splice_conn_init(&sc); 730 splice_conn_noblocking(&sc); 731 732 memset(buf, 'A', sizeof(buf)); 733 for (sofar = 0;;) { 734 n = write(sc.left[0], buf, sizeof(buf)); 735 if (n < 0) { 736 ATF_REQUIRE_ERRNO(EAGAIN, n == -1); 737 break; 738 } 739 sofar += n; 740 } 741 742 while (sofar > 0) { 743 n = read(sc.right[1], buf, sizeof(buf)); 744 if (n < 0) { 745 ATF_REQUIRE_ERRNO(EAGAIN, n == -1); 746 usleep(100); 747 } else { 748 for (size_t i = 0; i < (size_t)n; i++) 749 ATF_REQUIRE(buf[i] == 'A'); 750 sofar -= n; 751 } 752 } 753 754 splice_conn_fini(&sc); 755 } 756 757 ATF_TC_WITHOUT_HEAD(splice_resplice); 758 ATF_TC_BODY(splice_resplice, tc) 759 { 760 struct splice_conn sc; 761 ssize_t n; 762 char c; 763 764 splice_conn_init(&sc); 765 766 /* Left-to-right. */ 767 c = 'M'; 768 n = write(sc.left[0], &c, 1); 769 ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno)); 770 n = read(sc.right[1], &c, 1); 771 ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno)); 772 ATF_REQUIRE_MSG(c == 'M', "unexpected character: %c", c); 773 check_nspliced(sc.left[1], 1); 774 check_nspliced(sc.right[0], 0); 775 776 /* Right-to-left. */ 777 c = 'J'; 778 n = write(sc.right[1], &c, 1); 779 ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno)); 780 n = read(sc.left[0], &c, 1); 781 ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno)); 782 ATF_REQUIRE_MSG(c == 'J', "unexpected character: %c", c); 783 check_nspliced(sc.left[1], 1); 784 check_nspliced(sc.right[0], 1); 785 786 /* Unsplice and verify that the byte counts haven't changed. */ 787 unsplice(sc.left[1]); 788 unsplice(sc.right[0]); 789 check_nspliced(sc.left[1], 1); 790 check_nspliced(sc.right[0], 1); 791 792 /* Splice again, check that byte counts are reset. */ 793 splice_pair(sc.left[1], sc.right[0], 0, NULL); 794 check_nspliced(sc.left[1], 0); 795 check_nspliced(sc.right[0], 0); 796 797 /* Left-to-right. */ 798 c = 'M'; 799 n = write(sc.left[0], &c, 1); 800 ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno)); 801 n = read(sc.right[1], &c, 1); 802 ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno)); 803 ATF_REQUIRE_MSG(c == 'M', "unexpected character: %c", c); 804 check_nspliced(sc.left[1], 1); 805 check_nspliced(sc.right[0], 0); 806 807 /* Right-to-left. */ 808 c = 'J'; 809 n = write(sc.right[1], &c, 1); 810 ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno)); 811 n = read(sc.left[0], &c, 1); 812 ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno)); 813 ATF_REQUIRE_MSG(c == 'J', "unexpected character: %c", c); 814 check_nspliced(sc.left[1], 1); 815 check_nspliced(sc.right[0], 1); 816 817 splice_conn_fini(&sc); 818 } 819 820 struct xfer_args { 821 pthread_barrier_t *barrier; 822 uint32_t bytes; 823 int fd; 824 }; 825 826 static void * 827 xfer(void *arg) 828 { 829 struct xfer_args *xfer; 830 uint8_t *buf; 831 size_t sz; 832 ssize_t n; 833 uint32_t resid; 834 int error; 835 836 xfer = arg; 837 838 error = fcntl(xfer->fd, F_SETFL, O_NONBLOCK); 839 ATF_REQUIRE_MSG(error == 0, "fcntl failed: %s", strerror(errno)); 840 841 sz = MIN(xfer->bytes, 1024 * 1024); 842 buf = malloc(sz); 843 ATF_REQUIRE(buf != NULL); 844 arc4random_buf(buf, sz); 845 846 pthread_barrier_wait(xfer->barrier); 847 848 for (resid = xfer->bytes; xfer->bytes > 0 || resid > 0;) { 849 n = write(xfer->fd, buf, MIN(sz, xfer->bytes)); 850 if (n < 0) { 851 ATF_REQUIRE_ERRNO(EAGAIN, n == -1); 852 usleep(1000); 853 } else { 854 ATF_REQUIRE(xfer->bytes >= (size_t)n); 855 xfer->bytes -= n; 856 } 857 858 n = read(xfer->fd, buf, sz); 859 if (n < 0) { 860 ATF_REQUIRE_ERRNO(EAGAIN, n == -1); 861 usleep(1000); 862 } else { 863 ATF_REQUIRE(resid >= (size_t)n); 864 resid -= n; 865 } 866 } 867 868 free(buf); 869 return (NULL); 870 } 871 872 /* 873 * Use two threads to transfer data between two spliced connections. 874 */ 875 ATF_TC_WITHOUT_HEAD(splice_throughput); 876 ATF_TC_BODY(splice_throughput, tc) 877 { 878 struct xfer_args xfers[2]; 879 pthread_t thread[2]; 880 pthread_barrier_t barrier; 881 struct splice_conn sc; 882 uint32_t bytes; 883 int error; 884 885 /* Transfer an amount between 1B and 1GB. */ 886 bytes = arc4random_uniform(1024 * 1024 * 1024) + 1; 887 splice_conn_init(&sc); 888 889 error = pthread_barrier_init(&barrier, NULL, 2); 890 ATF_REQUIRE(error == 0); 891 xfers[0] = (struct xfer_args){ 892 .barrier = &barrier, 893 .bytes = bytes, 894 .fd = sc.left[0] 895 }; 896 xfers[1] = (struct xfer_args){ 897 .barrier = &barrier, 898 .bytes = bytes, 899 .fd = sc.right[1] 900 }; 901 902 error = pthread_create(&thread[0], NULL, xfer, &xfers[0]); 903 ATF_REQUIRE_MSG(error == 0, 904 "pthread_create failed: %s", strerror(errno)); 905 error = pthread_create(&thread[1], NULL, xfer, &xfers[1]); 906 ATF_REQUIRE_MSG(error == 0, 907 "pthread_create failed: %s", strerror(errno)); 908 909 error = pthread_join(thread[0], NULL); 910 ATF_REQUIRE_MSG(error == 0, 911 "pthread_join failed: %s", strerror(errno)); 912 error = pthread_join(thread[1], NULL); 913 ATF_REQUIRE_MSG(error == 0, 914 "pthread_join failed: %s", strerror(errno)); 915 916 error = pthread_barrier_destroy(&barrier); 917 ATF_REQUIRE(error == 0); 918 splice_conn_fini(&sc); 919 } 920 921 /* 922 * Make sure it's possible to splice v4 and v6 sockets together. 923 */ 924 ATF_TC_WITHOUT_HEAD(splice_v4v6); 925 ATF_TC_BODY(splice_v4v6, tc) 926 { 927 struct splice sp; 928 ssize_t n; 929 int sd4[2], sd6[2]; 930 int error; 931 uint8_t b; 932 933 tcp4_socketpair(sd4); 934 tcp6_socketpair(sd6); 935 936 splice_init(&sp, sd6[0], 0, NULL); 937 error = setsockopt(sd4[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 938 ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno)); 939 940 splice_init(&sp, sd4[1], 0, NULL); 941 error = setsockopt(sd6[0], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)); 942 ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno)); 943 944 b = 'M'; 945 n = write(sd4[0], &b, 1); 946 ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno)); 947 n = read(sd6[1], &b, 1); 948 ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno)); 949 ATF_REQUIRE(b == 'M'); 950 951 b = 'J'; 952 n = write(sd6[1], &b, 1); 953 ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno)); 954 n = read(sd4[0], &b, 1); 955 ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno)); 956 ATF_REQUIRE(b == 'J'); 957 958 checked_close(sd4[0]); 959 checked_close(sd4[1]); 960 checked_close(sd6[0]); 961 checked_close(sd6[1]); 962 } 963 964 ATF_TP_ADD_TCS(tp) 965 { 966 ATF_TP_ADD_TC(tp, splice_basic); 967 ATF_TP_ADD_TC(tp, splice_capsicum); 968 ATF_TP_ADD_TC(tp, splice_error); 969 ATF_TP_ADD_TC(tp, splice_kevent); 970 ATF_TP_ADD_TC(tp, splice_limit_bytes); 971 ATF_TP_ADD_TC(tp, splice_limit_timeout); 972 ATF_TP_ADD_TC(tp, splice_listen); 973 ATF_TP_ADD_TC(tp, splice_loop); 974 ATF_TP_ADD_TC(tp, splice_nonblock); 975 ATF_TP_ADD_TC(tp, splice_resplice); 976 ATF_TP_ADD_TC(tp, splice_throughput); 977 ATF_TP_ADD_TC(tp, splice_v4v6); 978 return (atf_no_error()); 979 } 980