1 /*- 2 * Copyright (c) 2008 Isilon Inc http://www.isilon.com/ 3 * Authors: Doug Rabson <dfr@rabson.org> 4 * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD: src/tools/regression/file/flock/flock.c,v 1.3 2008/06/26 10:21:54 dfr Exp $ 28 */ 29 30 #include <sys/time.h> 31 #include <sys/stat.h> 32 33 #include <err.h> 34 #include <errno.h> 35 #include <fcntl.h> 36 #include <limits.h> 37 #include <signal.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <termios.h> 42 #include <unistd.h> 43 #include <util.h> 44 45 #include "util.h" 46 47 int verbose = 0; 48 49 static void 50 ignore_alarm(int __unused sig) 51 { 52 } 53 54 static int 55 safe_kill(pid_t pid, int sig) 56 { 57 int save_errno; 58 int status; 59 60 save_errno = errno; 61 errno = 0; 62 status = kill(pid, sig); 63 errno = save_errno; 64 65 return (status); 66 } 67 68 /* 69 * Test 1 - F_GETLK on unlocked region 70 * 71 * If no lock is found that would prevent this lock from being 72 * created, the structure is left unchanged by this function call 73 * except for the lock type which is set to F_UNLCK. 74 */ 75 static int 76 test1(int fd) 77 { 78 struct flock fl1, fl2; 79 80 memset(&fl1, 1, sizeof(fl1)); 81 fl1.l_type = F_WRLCK; 82 fl1.l_whence = SEEK_SET; 83 fl2 = fl1; 84 85 if (fcntl(fd, F_GETLK, &fl1) < 0) 86 err(1, "F_GETLK"); 87 88 if (verbose) printf("1 - F_GETLK on unlocked region: "); 89 FAIL(fl1.l_start != fl2.l_start); 90 FAIL(fl1.l_len != fl2.l_len); 91 FAIL(fl1.l_pid != fl2.l_pid); 92 FAIL(fl1.l_type != F_UNLCK); 93 FAIL(fl1.l_whence != fl2.l_whence); 94 95 SUCCEED; 96 } 97 98 /* 99 * Test 2 - F_SETLK on locked region 100 * 101 * If a shared or exclusive lock cannot be set, fcntl returns 102 * immediately with EACCES or EAGAIN. 103 */ 104 static int 105 test2(int fd) 106 { 107 /* 108 * We create a child process to hold the lock which we will 109 * test. We use a pipe to communicate with the child. 110 */ 111 int pid; 112 int pfd[2]; 113 struct flock fl; 114 char ch; 115 int res; 116 117 if (pipe(pfd) < 0) 118 err(1, "pipe"); 119 120 fl.l_start = 0; 121 fl.l_len = 0; 122 fl.l_type = F_WRLCK; 123 fl.l_whence = SEEK_SET; 124 125 pid = fork(); 126 if (pid < 0) 127 err(1, "fork"); 128 129 if (pid == 0) { 130 /* 131 * We are the child. We set a write lock and then 132 * write one byte back to the parent to tell it. The 133 * parent will kill us when its done. 134 */ 135 if (fcntl(fd, F_SETLK, &fl) < 0) 136 err(1, "F_SETLK (child)"); 137 if (write(pfd[1], "a", 1) < 0) 138 err(1, "writing to pipe (child)"); 139 pause(); 140 exit(0); 141 } 142 143 /* 144 * Wait until the child has set its lock and then perform the 145 * test. 146 */ 147 if (read(pfd[0], &ch, 1) != 1) 148 err(1, "reading from pipe (child)"); 149 150 /* 151 * fcntl should return -1 with errno set to either EACCES or 152 * EAGAIN. 153 */ 154 if (verbose) printf("2 - F_SETLK on locked region: "); 155 res = fcntl(fd, F_SETLK, &fl); 156 safe_kill(pid, SIGTERM); 157 safe_waitpid(pid); 158 close(pfd[0]); 159 close(pfd[1]); 160 FAIL(res == 0); 161 FAIL(errno != EACCES && errno != EAGAIN); 162 163 SUCCEED; 164 } 165 166 /* 167 * Test 3 - F_SETLKW on locked region 168 * 169 * If a shared or exclusive lock is blocked by other locks, the 170 * process waits until the request can be satisfied. 171 * 172 * XXX this test hangs on FreeBSD NFS filesystems due to limitations 173 * in FreeBSD's client (and server) lockd implementation. 174 */ 175 static int 176 test3(int fd) 177 { 178 /* 179 * We create a child process to hold the lock which we will 180 * test. We use a pipe to communicate with the child. 181 */ 182 int pid; 183 int pfd[2]; 184 struct flock fl; 185 char ch; 186 int res; 187 188 if (pipe(pfd) < 0) 189 err(1, "pipe"); 190 191 fl.l_start = 0; 192 fl.l_len = 0; 193 fl.l_type = F_WRLCK; 194 fl.l_whence = SEEK_SET; 195 196 pid = fork(); 197 if (pid < 0) 198 err(1, "fork"); 199 200 if (pid == 0) { 201 /* 202 * We are the child. We set a write lock and then 203 * write one byte back to the parent to tell it. The 204 * parent will kill us when its done. 205 */ 206 if (fcntl(fd, F_SETLK, &fl) < 0) 207 err(1, "F_SETLK (child)"); 208 if (write(pfd[1], "a", 1) < 0) 209 err(1, "writing to pipe (child)"); 210 pause(); 211 exit(0); 212 } 213 214 /* 215 * Wait until the child has set its lock and then perform the 216 * test. 217 */ 218 if (read(pfd[0], &ch, 1) != 1) 219 err(1, "reading from pipe (child)"); 220 221 /* 222 * fcntl should wait until the alarm and then return -1 with 223 * errno set to EINTR. 224 */ 225 if (verbose) printf("3 - F_SETLKW on locked region: "); 226 227 alarm(1); 228 229 res = fcntl(fd, F_SETLKW, &fl); 230 safe_kill(pid, SIGTERM); 231 safe_waitpid(pid); 232 close(pfd[0]); 233 close(pfd[1]); 234 FAIL(res == 0); 235 FAIL(errno != EINTR); 236 237 SUCCEED; 238 } 239 240 /* 241 * Test 4 - F_GETLK on locked region 242 * 243 * Get the first lock that blocks the lock. 244 */ 245 static int 246 test4(int fd) 247 { 248 /* 249 * We create a child process to hold the lock which we will 250 * test. We use a pipe to communicate with the child. 251 */ 252 int pid; 253 int pfd[2]; 254 struct flock fl; 255 char ch; 256 257 if (pipe(pfd) < 0) 258 err(1, "pipe"); 259 260 fl.l_start = 0; 261 fl.l_len = 99; 262 fl.l_type = F_WRLCK; 263 fl.l_whence = SEEK_SET; 264 265 pid = fork(); 266 if (pid < 0) 267 err(1, "fork"); 268 269 if (pid == 0) { 270 /* 271 * We are the child. We set a write lock and then 272 * write one byte back to the parent to tell it. The 273 * parent will kill us when its done. 274 */ 275 if (fcntl(fd, F_SETLK, &fl) < 0) 276 err(1, "F_SETLK (child)"); 277 if (write(pfd[1], "a", 1) < 0) 278 err(1, "writing to pipe (child)"); 279 pause(); 280 exit(0); 281 } 282 283 /* 284 * Wait until the child has set its lock and then perform the 285 * test. 286 */ 287 if (read(pfd[0], &ch, 1) != 1) 288 err(1, "reading from pipe (child)"); 289 290 /* 291 * fcntl should return a lock structure reflecting the lock we 292 * made in the child process. 293 */ 294 if (fcntl(fd, F_GETLK, &fl) < 0) 295 err(1, "F_GETLK"); 296 297 if (verbose) printf("4 - F_GETLK on locked region: "); 298 FAIL(fl.l_start != 0); 299 FAIL(fl.l_len != 99); 300 FAIL(fl.l_type != F_WRLCK); 301 FAIL(fl.l_pid != pid); 302 303 safe_kill(pid, SIGTERM); 304 safe_waitpid(pid); 305 close(pfd[0]); 306 close(pfd[1]); 307 308 SUCCEED; 309 } 310 311 /* 312 * Test 5 - F_SETLKW simple deadlock 313 * 314 * If a blocking shared lock request would cause a deadlock (i.e. the 315 * lock request is blocked by a process which is itself blocked on a 316 * lock currently owned by the process making the new request), 317 * EDEADLK is returned. 318 */ 319 static int 320 test5(int fd) 321 { 322 /* 323 * We create a child process to hold the lock which we will 324 * test. Because our test relies on the child process being 325 * blocked on the parent's lock, we can't easily use a pipe to 326 * synchronize so we just sleep in the parent to given the 327 * child a chance to setup. 328 * 329 * To create the deadlock condition, we arrange for the parent 330 * to lock the first byte of the file and the child to lock 331 * the second byte. After locking the second byte, the child 332 * will attempt to lock the first byte of the file, and 333 * block. The parent will then attempt to lock the second byte 334 * (owned by the child) which should cause deadlock. 335 */ 336 int pid; 337 struct flock fl; 338 int res; 339 340 /* 341 * Lock the first byte in the parent. 342 */ 343 fl.l_start = 0; 344 fl.l_len = 1; 345 fl.l_type = F_WRLCK; 346 fl.l_whence = SEEK_SET; 347 if (fcntl(fd, F_SETLK, &fl) < 0) 348 err(1, "F_SETLK 1 (parent)"); 349 350 pid = fork(); 351 if (pid < 0) 352 err(1, "fork"); 353 354 if (pid == 0) { 355 /* 356 * Lock the second byte in the child and then block on 357 * the parent's lock. 358 */ 359 fl.l_start = 1; 360 if (fcntl(fd, F_SETLK, &fl) < 0) 361 err(1, "F_SETLK (child)"); 362 fl.l_start = 0; 363 if (fcntl(fd, F_SETLKW, &fl) < 0) 364 err(1, "F_SETLKW (child)"); 365 exit(0); 366 } 367 368 /* 369 * Wait until the child has set its lock and then perform the 370 * test. 371 */ 372 sleep(1); 373 374 /* 375 * fcntl should immediately return -1 with errno set to 376 * EDEADLK. If the alarm fires, we failed to detect the 377 * deadlock. 378 */ 379 alarm(1); 380 if (verbose) printf("5 - F_SETLKW simple deadlock: "); 381 382 fl.l_start = 1; 383 res = fcntl(fd, F_SETLKW, &fl); 384 safe_kill(pid, SIGTERM); 385 safe_waitpid(pid); 386 387 FAIL(res == 0); 388 FAIL(errno != EDEADLK); 389 390 fl.l_start = 0; 391 fl.l_len = 0; 392 fl.l_type = F_UNLCK; 393 if (fcntl(fd, F_SETLK, &fl) < 0) 394 err(1, "F_UNLCK"); 395 396 /* 397 * Cancel the alarm to avoid confusing later tests. 398 */ 399 alarm(0); 400 401 SUCCEED; 402 } 403 404 /* 405 * Test 6 - F_SETLKW complex deadlock. 406 * 407 * This test involves three process, P, C1 and C2. We set things up so 408 * that P locks byte zero, C1 locks byte 1 and C2 locks byte 2. We 409 * also block C2 by attempting to lock byte zero. Lastly, P attempts 410 * to lock a range including byte 1 and 2. This represents a deadlock 411 * (due to C2's blocking attempt to lock byte zero). 412 */ 413 static int 414 test6(int fd) 415 { 416 /* 417 * Because our test relies on the child process being blocked 418 * on the parent's lock, we can't easily use a pipe to 419 * synchronize so we just sleep in the parent to given the 420 * children a chance to setup. 421 */ 422 int pid1, pid2; 423 struct flock fl; 424 int res; 425 426 /* 427 * Lock the first byte in the parent. 428 */ 429 fl.l_start = 0; 430 fl.l_len = 1; 431 fl.l_type = F_WRLCK; 432 fl.l_whence = SEEK_SET; 433 if (fcntl(fd, F_SETLK, &fl) < 0) 434 err(1, "F_SETLK 1 (parent)"); 435 436 pid1 = fork(); 437 if (pid1 < 0) 438 err(1, "fork"); 439 440 if (pid1 == 0) { 441 /* 442 * C1 443 * Lock the second byte in the child and then sleep 444 */ 445 fl.l_start = 1; 446 if (fcntl(fd, F_SETLK, &fl) < 0) 447 err(1, "F_SETLK (child1)"); 448 pause(); 449 exit(0); 450 } 451 452 pid2 = fork(); 453 if (pid2 < 0) 454 err(1, "fork"); 455 456 if (pid2 == 0) { 457 /* 458 * C2 459 * Lock the third byte in the child and then block on 460 * the parent's lock. 461 */ 462 fl.l_start = 2; 463 if (fcntl(fd, F_SETLK, &fl) < 0) 464 err(1, "F_SETLK (child2)"); 465 fl.l_start = 0; 466 if (fcntl(fd, F_SETLKW, &fl) < 0) 467 err(1, "F_SETLKW (child2)"); 468 exit(0); 469 } 470 471 /* 472 * Wait until the children have set their locks and then 473 * perform the test. 474 */ 475 sleep(1); 476 477 /* 478 * fcntl should immediately return -1 with errno set to 479 * EDEADLK. If the alarm fires, we failed to detect the 480 * deadlock. 481 */ 482 alarm(1); 483 if (verbose) printf("6 - F_SETLKW complex deadlock: "); 484 485 fl.l_start = 1; 486 fl.l_len = 2; 487 res = fcntl(fd, F_SETLKW, &fl); 488 safe_kill(pid1, SIGTERM); 489 safe_waitpid(pid1); 490 safe_kill(pid2, SIGTERM); 491 safe_waitpid(pid2); 492 493 fl.l_start = 0; 494 fl.l_len = 0; 495 fl.l_type = F_UNLCK; 496 if (fcntl(fd, F_SETLK, &fl) < 0) 497 err(1, "F_UNLCK"); 498 499 FAIL(res == 0); 500 FAIL(errno != EDEADLK); 501 502 /* 503 * Cancel the alarm to avoid confusing later tests. 504 */ 505 alarm(0); 506 507 SUCCEED; 508 } 509 510 /* 511 * Test 7 - F_SETLK shared lock on exclusive locked region 512 * 513 * If a shared or exclusive lock cannot be set, fcntl returns 514 * immediately with EACCES or EAGAIN. 515 */ 516 static int 517 test7(int fd) 518 { 519 /* 520 * We create a child process to hold the lock which we will 521 * test. We use a pipe to communicate with the child. 522 */ 523 int pid; 524 int pfd[2]; 525 struct flock fl; 526 char ch; 527 int res; 528 529 if (pipe(pfd) < 0) 530 err(1, "pipe"); 531 532 fl.l_start = 0; 533 fl.l_len = 0; 534 fl.l_type = F_WRLCK; 535 fl.l_whence = SEEK_SET; 536 537 pid = fork(); 538 if (pid < 0) 539 err(1, "fork"); 540 541 if (pid == 0) { 542 /* 543 * We are the child. We set a write lock and then 544 * write one byte back to the parent to tell it. The 545 * parent will kill us when its done. 546 */ 547 if (fcntl(fd, F_SETLK, &fl) < 0) 548 err(1, "F_SETLK (child)"); 549 if (write(pfd[1], "a", 1) < 0) 550 err(1, "writing to pipe (child)"); 551 pause(); 552 exit(0); 553 } 554 555 /* 556 * Wait until the child has set its lock and then perform the 557 * test. 558 */ 559 if (read(pfd[0], &ch, 1) != 1) 560 err(1, "reading from pipe (child)"); 561 562 /* 563 * fcntl should wait until the alarm and then return -1 with 564 * errno set to EINTR. 565 */ 566 if (verbose) printf("7 - F_SETLK shared lock on exclusive locked region: "); 567 568 fl.l_type = F_RDLCK; 569 res = fcntl(fd, F_SETLK, &fl); 570 safe_kill(pid, SIGTERM); 571 safe_waitpid(pid); 572 close(pfd[0]); 573 close(pfd[1]); 574 575 FAIL(res == 0); 576 FAIL(errno != EACCES && errno != EAGAIN); 577 578 SUCCEED; 579 } 580 581 /* 582 * Test 8 - F_SETLK shared lock on share locked region 583 * 584 * When a shared lock is set on a segment of a file, other processes 585 * shall be able to set shared locks on that segment or a portion of 586 * it. 587 */ 588 static int 589 test8(int fd) 590 { 591 /* 592 * We create a child process to hold the lock which we will 593 * test. We use a pipe to communicate with the child. 594 */ 595 int pid; 596 int pfd[2]; 597 struct flock fl; 598 char ch; 599 int res; 600 601 if (pipe(pfd) < 0) 602 err(1, "pipe"); 603 604 fl.l_start = 0; 605 fl.l_len = 0; 606 fl.l_type = F_RDLCK; 607 fl.l_whence = SEEK_SET; 608 609 pid = fork(); 610 if (pid < 0) 611 err(1, "fork"); 612 613 if (pid == 0) { 614 /* 615 * We are the child. We set a write lock and then 616 * write one byte back to the parent to tell it. The 617 * parent will kill us when its done. 618 */ 619 if (fcntl(fd, F_SETLK, &fl) < 0) 620 err(1, "F_SETLK (child)"); 621 if (write(pfd[1], "a", 1) < 0) 622 err(1, "writing to pipe (child)"); 623 pause(); 624 exit(0); 625 } 626 627 /* 628 * Wait until the child has set its lock and then perform the 629 * test. 630 */ 631 if (read(pfd[0], &ch, 1) != 1) 632 err(1, "reading from pipe (child)"); 633 634 /* 635 * fcntl should wait until the alarm and then return -1 with 636 * errno set to EINTR. 637 */ 638 if (verbose) printf("8 - F_SETLK shared lock on share locked region: "); 639 640 fl.l_type = F_RDLCK; 641 res = fcntl(fd, F_SETLK, &fl); 642 643 safe_kill(pid, SIGTERM); 644 safe_waitpid(pid); 645 close(pfd[0]); 646 close(pfd[1]); 647 648 fl.l_start = 0; 649 fl.l_len = 0; 650 fl.l_type = F_UNLCK; 651 if (fcntl(fd, F_SETLK, &fl) < 0) 652 err(1, "F_UNLCK"); 653 654 FAIL(res != 0); 655 656 SUCCEED; 657 } 658 659 /* 660 * Test 9 - F_SETLK exclusive lock on share locked region 661 * 662 * If a shared or exclusive lock cannot be set, fcntl returns 663 * immediately with EACCES or EAGAIN. 664 */ 665 static int 666 test9(int fd) 667 { 668 /* 669 * We create a child process to hold the lock which we will 670 * test. We use a pipe to communicate with the child. 671 */ 672 int pid; 673 int pfd[2]; 674 struct flock fl; 675 char ch; 676 int res; 677 678 if (pipe(pfd) < 0) 679 err(1, "pipe"); 680 681 fl.l_start = 0; 682 fl.l_len = 0; 683 fl.l_type = F_RDLCK; 684 fl.l_whence = SEEK_SET; 685 686 pid = fork(); 687 if (pid < 0) 688 err(1, "fork"); 689 690 if (pid == 0) { 691 /* 692 * We are the child. We set a write lock and then 693 * write one byte back to the parent to tell it. The 694 * parent will kill us when its done. 695 */ 696 if (fcntl(fd, F_SETLK, &fl) < 0) 697 err(1, "F_SETLK (child)"); 698 if (write(pfd[1], "a", 1) < 0) 699 err(1, "writing to pipe (child)"); 700 pause(); 701 exit(0); 702 } 703 704 /* 705 * Wait until the child has set its lock and then perform the 706 * test. 707 */ 708 if (read(pfd[0], &ch, 1) != 1) 709 err(1, "reading from pipe (child)"); 710 711 /* 712 * fcntl should wait until the alarm and then return -1 with 713 * errno set to EINTR. 714 */ 715 if (verbose) printf("9 - F_SETLK exclusive lock on share locked region: "); 716 717 fl.l_type = F_WRLCK; 718 res = fcntl(fd, F_SETLK, &fl); 719 safe_kill(pid, SIGTERM); 720 safe_waitpid(pid); 721 close(pfd[0]); 722 close(pfd[1]); 723 724 FAIL(res == 0); 725 FAIL(errno != EACCES && errno != EAGAIN); 726 727 SUCCEED; 728 } 729 730 /* 731 * Test 10 - trying to set bogus pid or sysid values 732 * 733 * The l_pid and l_sysid fields are only used with F_GETLK to return 734 * the process ID of the process holding a blocking lock and the 735 * system ID of the system that owns that process 736 */ 737 static int 738 test10(int fd) 739 { 740 /* 741 * We create a child process to hold the lock which we will 742 * test. We use a pipe to communicate with the child. 743 */ 744 int pid; 745 int pfd[2]; 746 struct flock fl; 747 char ch; 748 749 if (pipe(pfd) < 0) 750 err(1, "pipe"); 751 752 fl.l_start = 0; 753 fl.l_len = 0; 754 fl.l_type = F_WRLCK; 755 fl.l_whence = SEEK_SET; 756 fl.l_pid = 9999; 757 758 pid = fork(); 759 if (pid < 0) 760 err(1, "fork"); 761 762 if (pid == 0) { 763 /* 764 * We are the child. We set a write lock and then 765 * write one byte back to the parent to tell it. The 766 * parent will kill us when its done. 767 */ 768 if (fcntl(fd, F_SETLK, &fl) < 0) 769 err(1, "F_SETLK (child)"); 770 if (write(pfd[1], "a", 1) < 0) 771 err(1, "writing to pipe (child)"); 772 pause(); 773 exit(0); 774 } 775 776 /* 777 * Wait until the child has set its lock and then perform the 778 * test. 779 */ 780 if (read(pfd[0], &ch, 1) != 1) 781 err(1, "reading from pipe (child)"); 782 783 if (verbose) printf("10 - trying to set bogus pid or sysid values: "); 784 785 if (fcntl(fd, F_GETLK, &fl) < 0) 786 err(1, "F_GETLK"); 787 788 safe_kill(pid, SIGTERM); 789 safe_waitpid(pid); 790 close(pfd[0]); 791 close(pfd[1]); 792 793 FAIL(fl.l_pid != pid); 794 795 SUCCEED; 796 } 797 798 /* 799 * Test 11 - remote locks 800 * 801 * XXX temporary interface which will be removed when the kernel lockd 802 * is added. 803 */ 804 static int 805 test11(int fd) 806 { 807 #ifdef F_SETLK_REMOTE 808 struct flock fl; 809 int res; 810 811 if (geteuid() != 0) 812 return 0; 813 814 fl.l_start = 0; 815 fl.l_len = 0; 816 fl.l_type = F_WRLCK; 817 fl.l_whence = SEEK_SET; 818 fl.l_pid = 9999; 819 fl.l_sysid = 1001; 820 821 if (verbose) printf("11 - remote locks: "); 822 823 res = fcntl(fd, F_SETLK_REMOTE, &fl); 824 FAIL(res != 0); 825 826 fl.l_sysid = 1002; 827 res = fcntl(fd, F_SETLK_REMOTE, &fl); 828 FAIL(res == 0); 829 FAIL(errno != EACCES && errno != EAGAIN); 830 831 res = fcntl(fd, F_GETLK, &fl); 832 FAIL(res != 0); 833 FAIL(fl.l_pid != 9999); 834 FAIL(fl.l_sysid != 1001); 835 836 fl.l_type = F_UNLCK; 837 fl.l_sysid = 1001; 838 fl.l_start = 0; 839 fl.l_len = 0; 840 res = fcntl(fd, F_SETLK_REMOTE, &fl); 841 FAIL(res != 0); 842 843 fl.l_pid = 1234; 844 fl.l_sysid = 1001; 845 fl.l_start = 0; 846 fl.l_len = 1; 847 fl.l_whence = SEEK_SET; 848 fl.l_type = F_RDLCK; 849 res = fcntl(fd, F_SETLK_REMOTE, &fl); 850 FAIL(res != 0); 851 852 fl.l_sysid = 1002; 853 res = fcntl(fd, F_SETLK_REMOTE, &fl); 854 FAIL(res != 0); 855 856 fl.l_type = F_UNLCKSYS; 857 fl.l_sysid = 1001; 858 res = fcntl(fd, F_SETLK_REMOTE, &fl); 859 FAIL(res != 0); 860 861 fl.l_type = F_WRLCK; 862 res = fcntl(fd, F_GETLK, &fl); 863 FAIL(res != 0); 864 FAIL(fl.l_pid != 1234); 865 FAIL(fl.l_sysid != 1002); 866 867 fl.l_type = F_UNLCKSYS; 868 fl.l_sysid = 1002; 869 res = fcntl(fd, F_SETLK_REMOTE, &fl); 870 FAIL(res != 0); 871 872 SUCCEED; 873 #else 874 return 0; 875 #endif 876 } 877 878 /* 879 * Test 12 - F_SETLKW on locked region which is then unlocked 880 * 881 * If a shared or exclusive lock is blocked by other locks, the 882 * process waits until the request can be satisfied. 883 */ 884 static int 885 test12(int fd) 886 { 887 /* 888 * We create a child process to hold the lock which we will 889 * test. We use a pipe to communicate with the child. 890 */ 891 int pid; 892 int pfd[2]; 893 struct flock fl; 894 char ch; 895 int res; 896 897 if (pipe(pfd) < 0) 898 err(1, "pipe"); 899 900 fl.l_start = 0; 901 fl.l_len = 0; 902 fl.l_type = F_WRLCK; 903 fl.l_whence = SEEK_SET; 904 905 pid = fork(); 906 if (pid < 0) 907 err(1, "fork"); 908 909 if (pid == 0) { 910 /* 911 * We are the child. We set a write lock and then 912 * write one byte back to the parent to tell it. The 913 * parent will kill us when its done. 914 */ 915 if (fcntl(fd, F_SETLK, &fl) < 0) 916 err(1, "F_SETLK (child)"); 917 if (write(pfd[1], "a", 1) < 0) 918 err(1, "writing to pipe (child)"); 919 920 sleep(1); 921 exit(0); 922 } 923 924 /* 925 * Wait until the child has set its lock and then perform the 926 * test. 927 */ 928 if (read(pfd[0], &ch, 1) != 1) 929 err(1, "reading from pipe (child)"); 930 931 /* 932 * fcntl should wait until the alarm and then return -1 with 933 * errno set to EINTR. 934 */ 935 if (verbose) printf("12 - F_SETLKW on locked region which is then unlocked: "); 936 937 //alarm(1); 938 939 res = fcntl(fd, F_SETLKW, &fl); 940 safe_kill(pid, SIGTERM); 941 safe_waitpid(pid); 942 close(pfd[0]); 943 close(pfd[1]); 944 FAIL(res != 0); 945 946 fl.l_start = 0; 947 fl.l_len = 0; 948 fl.l_type = F_UNLCK; 949 if (fcntl(fd, F_SETLK, &fl) < 0) 950 err(1, "F_UNLCK"); 951 952 SUCCEED; 953 } 954 955 /* 956 * Test 13 - F_SETLKW on locked region, race with owner 957 * 958 * If a shared or exclusive lock is blocked by other locks, the 959 * process waits until the request can be satisfied. 960 */ 961 static int 962 test13(int fd) 963 { 964 /* 965 * We create a child process to hold the lock which we will 966 * test. We use a pipe to communicate with the child. 967 */ 968 int i; 969 int pid; 970 int pfd[2]; 971 struct flock fl; 972 char ch; 973 int res; 974 struct itimerval itv; 975 976 if (verbose) printf("13 - F_SETLKW on locked region, race with owner: "); 977 fflush(stdout); 978 979 for (i = 0; i < 100; i++) { 980 if (pipe(pfd) < 0) 981 err(1, "pipe"); 982 983 fl.l_start = 0; 984 fl.l_len = 0; 985 fl.l_type = F_WRLCK; 986 fl.l_whence = SEEK_SET; 987 988 pid = fork(); 989 if (pid < 0) 990 err(1, "fork"); 991 992 if (pid == 0) { 993 /* 994 * We are the child. We set a write lock and then 995 * write one byte back to the parent to tell it. The 996 * parent will kill us when its done. 997 */ 998 if (fcntl(fd, F_SETLK, &fl) < 0) 999 err(1, "F_SETLK (child)"); 1000 if (write(pfd[1], "a", 1) < 0) 1001 err(1, "writing to pipe (child)"); 1002 1003 sleep(1); 1004 exit(0); 1005 } 1006 1007 /* 1008 * Wait until the child has set its lock and then perform the 1009 * test. 1010 */ 1011 while (read(pfd[0], &ch, 1) != 1) { 1012 if (errno == EINTR) 1013 continue; 1014 err(1, "reading from pipe (child)"); 1015 } 1016 1017 /* 1018 * fcntl should wait until the alarm and then return -1 with 1019 * errno set to EINTR. 1020 */ 1021 itv.it_interval.tv_sec = 0; 1022 itv.it_interval.tv_usec = 0; 1023 itv.it_value.tv_sec = 0; 1024 itv.it_value.tv_usec = 2; 1025 setitimer(ITIMER_REAL, &itv, NULL); 1026 1027 res = fcntl(fd, F_SETLKW, &fl); 1028 safe_kill(pid, SIGTERM); 1029 safe_waitpid(pid); 1030 close(pfd[0]); 1031 close(pfd[1]); 1032 FAIL(!(res == 0 || (res == -1 && errno == EINTR))); 1033 1034 fl.l_start = 0; 1035 fl.l_len = 0; 1036 fl.l_type = F_UNLCK; 1037 if (fcntl(fd, F_SETLK, &fl) < 0) 1038 err(1, "F_UNLCK"); 1039 } 1040 SUCCEED; 1041 } 1042 1043 /* 1044 * Test 14 - soak test 1045 */ 1046 static int 1047 test14(int fd) 1048 { 1049 #define CHILD_COUNT 20 1050 /* 1051 * We create a set of child processes and let each one run 1052 * through a random sequence of locks and unlocks. 1053 */ 1054 int i, j, id; 1055 int pids[CHILD_COUNT], pid; 1056 char buf[128]; 1057 char tbuf[128]; 1058 int map[128]; 1059 char outbuf[512]; 1060 struct flock fl; 1061 struct itimerval itv; 1062 int status; 1063 int id_base = 0; 1064 1065 if (verbose) printf("14 - soak test: "); 1066 fflush(stdout); 1067 1068 for (i = 0; i < 128; i++) 1069 map[i] = F_UNLCK; 1070 1071 for (i = 0; i < CHILD_COUNT; i++) { 1072 1073 pid = fork(); 1074 if (pid < 0) 1075 err(1, "fork"); 1076 if (pid) { 1077 /* 1078 * Parent - record the pid and continue. 1079 */ 1080 pids[i] = pid; 1081 continue; 1082 } 1083 1084 /* 1085 * Child - do some work and exit. 1086 */ 1087 id = id_base + i; 1088 for (j = 0; j < 50; j++) { 1089 int start, end, len; 1090 int set, wrlock; 1091 1092 do { 1093 start = arc4random_uniform(128); 1094 end = arc4random_uniform(128); 1095 } while (end <= start); 1096 1097 set = arc4random_uniform(2); 1098 wrlock = arc4random_uniform(2); 1099 1100 len = end - start; 1101 fl.l_start = start; 1102 fl.l_len = len; 1103 fl.l_whence = SEEK_SET; 1104 if (set) 1105 fl.l_type = wrlock ? F_WRLCK : F_RDLCK; 1106 else 1107 fl.l_type = F_UNLCK; 1108 1109 itv.it_interval.tv_sec = 0; 1110 itv.it_interval.tv_usec = 0; 1111 itv.it_value.tv_sec = 0; 1112 itv.it_value.tv_usec = 3000; 1113 setitimer(ITIMER_REAL, &itv, NULL); 1114 1115 if (fcntl(fd, F_SETLKW, &fl) < 0) { 1116 if (errno == EDEADLK || errno == EINTR) { 1117 if (verbose) { 1118 snprintf(outbuf, sizeof(outbuf), 1119 "%d[%d]: %s [%d .. %d] %s\n", 1120 id, j, 1121 set ? (wrlock ? "write lock" 1122 : "read lock") 1123 : "unlock", start, end, 1124 errno == EDEADLK 1125 ? "deadlock" 1126 : "interrupted"); 1127 write(1, outbuf, 1128 strlen(outbuf)); 1129 } 1130 continue; 1131 } else { 1132 perror("fcntl"); 1133 } 1134 } 1135 1136 itv.it_interval.tv_sec = 0; 1137 itv.it_interval.tv_usec = 0; 1138 itv.it_value.tv_sec = 0; 1139 itv.it_value.tv_usec = 0; 1140 setitimer(ITIMER_REAL, &itv, NULL); 1141 1142 if (verbose) { 1143 snprintf(outbuf, sizeof(outbuf), 1144 "%d[%d]: %s [%d .. %d] succeeded\n", 1145 id, j, 1146 set ? (wrlock ? "write lock" : "read lock") 1147 : "unlock", start, end); 1148 write(1, outbuf, strlen(outbuf)); 1149 } 1150 1151 if (set) { 1152 if (wrlock) { 1153 /* 1154 * We got a write lock - write 1155 * our ID to each byte that we 1156 * managed to claim. 1157 */ 1158 for (i = start; i < end; i++) 1159 map[i] = F_WRLCK; 1160 memset(&buf[start], id, len); 1161 if (pwrite(fd, &buf[start], len, 1162 start) != len) { 1163 printf("%d: short write\n", id); 1164 exit(1); 1165 } 1166 } else { 1167 /* 1168 * We got a read lock - read 1169 * the bytes which we claimed 1170 * so that we can check that 1171 * they don't change 1172 * unexpectedly. 1173 */ 1174 for (i = start; i < end; i++) 1175 map[i] = F_RDLCK; 1176 if (pread(fd, &buf[start], len, 1177 start) != len) { 1178 printf("%d: short read\n", id); 1179 exit(1); 1180 } 1181 } 1182 } else { 1183 for (i = start; i < end; i++) 1184 map[i] = F_UNLCK; 1185 } 1186 1187 usleep(1000); 1188 1189 /* 1190 * Read back the whole region so that we can 1191 * check that all the bytes we have some kind 1192 * of claim to have the correct value. 1193 */ 1194 if (pread(fd, tbuf, sizeof(tbuf), 0) != sizeof(tbuf)) { 1195 printf("%d: short read\n", id); 1196 exit(1); 1197 } 1198 1199 for (i = 0; i < 128; i++) { 1200 if (map[i] != F_UNLCK && buf[i] != tbuf[i]) { 1201 snprintf(outbuf, sizeof(outbuf), 1202 "%d: byte %d expected %d, " 1203 "got %d\n", id, i, buf[i], tbuf[i]); 1204 write(1, outbuf, strlen(outbuf)); 1205 exit(1); 1206 } 1207 } 1208 } 1209 if (verbose) 1210 printf("%d[%d]: done\n", id, j); 1211 1212 exit(0); 1213 } 1214 1215 status = 0; 1216 for (i = 0; i < CHILD_COUNT; i++) { 1217 status += safe_waitpid(pids[i]); 1218 } 1219 if (status) 1220 FAIL(status != 0); 1221 1222 SUCCEED; 1223 } 1224 1225 /* 1226 * Test 15 - flock(2) semantcs 1227 * 1228 * When a lock holder has a shared lock and attempts to upgrade that 1229 * shared lock to exclusive, it must drop the shared lock before 1230 * blocking on the exclusive lock. 1231 * 1232 * To test this, we first arrange for two shared locks on the file, 1233 * and then attempt to upgrade one of them to exclusive. This should 1234 * drop one of the shared locks and block. We interrupt the blocking 1235 * lock request and examine the lock state of the file after dropping 1236 * the other shared lock - there should be no active locks at this 1237 * point. 1238 */ 1239 static int 1240 test15(int fd) 1241 { 1242 #ifdef LOCK_EX 1243 /* 1244 * We create a child process to hold the lock which we will 1245 * test. We use a pipe to communicate with the child. 1246 * 1247 * Since we only have one file descriptors and lock ownership 1248 * for flock(2) goes with the file descriptor, we use fcntl to 1249 * set the child's shared lock. 1250 */ 1251 int pid; 1252 int pfd[2]; 1253 int fd2; 1254 struct flock fl; 1255 char ch; 1256 int res; 1257 1258 if (pipe(pfd) < 0) 1259 err(1, "pipe"); 1260 1261 pid = fork(); 1262 if (pid < 0) 1263 err(1, "fork"); 1264 1265 if (pid == 0) { 1266 /* 1267 * We are the child. We set a shared lock and then 1268 * write one byte back to the parent to tell it. The 1269 * parent will kill us when its done. 1270 */ 1271 fl.l_start = 0; 1272 fl.l_len = 0; 1273 fl.l_type = F_RDLCK; 1274 fl.l_whence = SEEK_SET; 1275 if (fcntl(fd, F_SETLK, &fl) < 0) 1276 err(1, "fcntl(F_SETLK) (child)"); 1277 if (write(pfd[1], "a", 1) < 0) 1278 err(1, "writing to pipe (child)"); 1279 pause(); 1280 exit(0); 1281 } 1282 1283 /* 1284 * Wait until the child has set its lock and then perform the 1285 * test. 1286 */ 1287 if (read(pfd[0], &ch, 1) != 1) 1288 err(1, "reading from pipe (child)"); 1289 1290 fd2 = dup(fd); 1291 FAIL(fd2 == -1); 1292 if (flock(fd, LOCK_SH) < 0) 1293 err(1, "flock shared"); 1294 1295 /* 1296 * flock should wait until the alarm and then return -1 with 1297 * errno set to EINTR. 1298 */ 1299 if (verbose) printf("15 - flock(2) semantics: "); 1300 1301 alarm(1); 1302 flock(fd, LOCK_EX); 1303 1304 /* 1305 * Kill the child to force it to drop its locks. 1306 */ 1307 safe_kill(pid, SIGTERM); 1308 safe_waitpid(pid); 1309 1310 fl.l_start = 0; 1311 fl.l_len = 0; 1312 fl.l_type = F_WRLCK; 1313 fl.l_whence = SEEK_SET; 1314 res = fcntl(fd, F_GETLK, &fl); 1315 1316 close(pfd[0]); 1317 close(pfd[1]); 1318 FAIL(res != 0); 1319 FAIL(fl.l_type != F_UNLCK); 1320 1321 SUCCEED; 1322 #else 1323 return 0; 1324 #endif 1325 } 1326 1327 /* 1328 * Test 16 - double free regression 1329 * 1330 * Not applicable anymore due to stricter bounds validation. 1331 */ 1332 static int 1333 test16(int fd) 1334 { 1335 #if 0 1336 struct flock fl; 1337 int res; 1338 1339 fl.l_pid = 0; 1340 fl.l_type = 1; 1341 fl.l_whence = 0; 1342 1343 fl.l_start = 0; 1344 fl.l_len = 0x8000000000000000; 1345 res = fcntl(fd, F_SETLK, &fl); 1346 FAIL(res != 0); 1347 1348 fl.l_start = 0x10000; 1349 fl.l_len = 0; 1350 res = fcntl(fd, F_SETLK, &fl); 1351 FAIL(res != 0); 1352 1353 fl.l_start = 0; 1354 fl.l_len = 0x8000000000000000; 1355 res = fcntl(fd, F_SETLK, &fl); 1356 FAIL(res != 0); 1357 1358 fl.l_start = 0x10000; 1359 fl.l_len = 0; 1360 res = fcntl(fd, F_SETLK, &fl); 1361 FAIL(res != 0); 1362 #endif 1363 1364 SUCCEED; 1365 } 1366 1367 /* 1368 * Test 17 - lf_findoverlap() case 0 1369 * 1370 * No overlap. 1371 */ 1372 static int 1373 test17(int fd) 1374 { 1375 struct flock fl; 1376 int nfd, res; 1377 1378 /* First lock. */ 1379 { 1380 nfd = dup(fd); 1381 FAIL(nfd == -1); 1382 1383 fl.l_start = 0; 1384 fl.l_len = 100; 1385 fl.l_pid = 0; 1386 fl.l_type = F_RDLCK; 1387 fl.l_whence = 0; 1388 res = fcntl(fd, F_SETLK, &fl); 1389 FAIL(res != 0); 1390 1391 close(nfd); 1392 } 1393 1394 /* Insert at end. */ 1395 { 1396 nfd = dup(fd); 1397 FAIL(nfd == -1); 1398 1399 fl.l_start = 100; 1400 fl.l_len = 100; 1401 fl.l_pid = 0; 1402 fl.l_type = F_RDLCK; 1403 fl.l_whence = 0; 1404 res = fcntl(fd, F_SETLK, &fl); 1405 FAIL(res != 0); 1406 1407 fl.l_start = 200; 1408 fl.l_len = 100; 1409 fl.l_pid = 0; 1410 fl.l_type = F_RDLCK; 1411 fl.l_whence = 0; 1412 res = fcntl(fd, F_SETLK, &fl); 1413 FAIL(res != 0); 1414 1415 close(nfd); 1416 } 1417 1418 /* Insert before overlap. */ 1419 { 1420 nfd = dup(fd); 1421 FAIL(nfd == -1); 1422 1423 fl.l_start = 300; 1424 fl.l_len = 100; 1425 fl.l_pid = 0; 1426 fl.l_type = F_RDLCK; 1427 fl.l_whence = 0; 1428 res = fcntl(fd, F_SETLK, &fl); 1429 FAIL(res != 0); 1430 1431 fl.l_start = 500; 1432 fl.l_len = 100; 1433 fl.l_pid = 0; 1434 fl.l_type = F_RDLCK; 1435 fl.l_whence = 0; 1436 res = fcntl(fd, F_SETLK, &fl); 1437 FAIL(res != 0); 1438 1439 fl.l_start = 400; 1440 fl.l_len = 100; 1441 fl.l_pid = 0; 1442 fl.l_type = F_RDLCK; 1443 fl.l_whence = 0; 1444 res = fcntl(fd, F_SETLK, &fl); 1445 FAIL(res != 0); 1446 1447 close(nfd); 1448 } 1449 1450 SUCCEED; 1451 } 1452 1453 /* 1454 * Test 18 - lf_findoverlap() case 1 1455 * 1456 * Overlap and lock are equal. 1457 */ 1458 static int 1459 test18(int fd) 1460 { 1461 struct flock fl; 1462 int res; 1463 1464 fl.l_start = 0; 1465 fl.l_len = 100; 1466 fl.l_pid = 0; 1467 fl.l_type = F_RDLCK; 1468 fl.l_whence = 0; 1469 res = fcntl(fd, F_SETLK, &fl); 1470 FAIL(res != 0); 1471 res = fcntl(fd, F_SETLK, &fl); 1472 FAIL(res != 0); 1473 1474 SUCCEED; 1475 } 1476 1477 /* 1478 * Test 19 - lf_findoverlap() case 2 1479 * 1480 * Overlap contains lock. 1481 */ 1482 static int 1483 test19(int fd) 1484 { 1485 struct flock fl; 1486 int nfd, res; 1487 1488 /* Same type. */ 1489 { 1490 nfd = dup(fd); 1491 FAIL(nfd == -1); 1492 1493 fl.l_start = 0; 1494 fl.l_len = 100; 1495 fl.l_pid = 0; 1496 fl.l_type = F_RDLCK; 1497 fl.l_whence = 0; 1498 res = fcntl(fd, F_SETLK, &fl); 1499 FAIL(res != 0); 1500 1501 fl.l_start = 0; 1502 fl.l_len = 50; 1503 fl.l_pid = 0; 1504 fl.l_type = F_RDLCK; 1505 fl.l_whence = 0; 1506 res = fcntl(fd, F_SETLK, &fl); 1507 FAIL(res != 0); 1508 1509 close(nfd); 1510 } 1511 1512 /* Different type, same start offset. */ 1513 { 1514 nfd = dup(fd); 1515 FAIL(nfd == -1); 1516 1517 fl.l_start = 100; 1518 fl.l_len = 100; 1519 fl.l_pid = 0; 1520 fl.l_type = F_RDLCK; 1521 fl.l_whence = 0; 1522 res = fcntl(fd, F_SETLK, &fl); 1523 FAIL(res != 0); 1524 1525 fl.l_start = 100; 1526 fl.l_len = 50; 1527 fl.l_pid = 0; 1528 fl.l_type = F_WRLCK; 1529 fl.l_whence = 0; 1530 res = fcntl(fd, F_SETLK, &fl); 1531 FAIL(res != 0); 1532 1533 close(nfd); 1534 } 1535 1536 /* Split fallback. */ 1537 { 1538 nfd = dup(fd); 1539 FAIL(nfd == -1); 1540 1541 fl.l_start = 100; 1542 fl.l_len = 100; 1543 fl.l_pid = 0; 1544 fl.l_type = F_RDLCK; 1545 fl.l_whence = 0; 1546 res = fcntl(fd, F_SETLK, &fl); 1547 FAIL(res != 0); 1548 1549 fl.l_start = 110; 1550 fl.l_len = 50; 1551 fl.l_pid = 0; 1552 fl.l_type = F_WRLCK; 1553 fl.l_whence = 0; 1554 res = fcntl(fd, F_SETLK, &fl); 1555 FAIL(res != 0); 1556 1557 close(nfd); 1558 } 1559 1560 SUCCEED; 1561 } 1562 1563 /* 1564 * Test 20 - lf_findoverlap() case 3 1565 * 1566 * Lock contains overlap. 1567 */ 1568 static int 1569 test20(int fd) 1570 { 1571 struct flock fl; 1572 int res; 1573 1574 fl.l_start = 0; 1575 fl.l_len = 100; 1576 fl.l_pid = 0; 1577 fl.l_type = F_WRLCK; 1578 fl.l_whence = 0; 1579 res = fcntl(fd, F_SETLK, &fl); 1580 FAIL(res != 0); 1581 1582 fl.l_start = 0; 1583 fl.l_len = 200; 1584 fl.l_pid = 0; 1585 fl.l_type = F_WRLCK; 1586 fl.l_whence = 0; 1587 res = fcntl(fd, F_SETLK, &fl); 1588 FAIL(res != 0); 1589 1590 SUCCEED; 1591 } 1592 1593 /* 1594 * Test 21 - lf_findoverlap() case 4 1595 * 1596 * Overlap starts before lock. 1597 */ 1598 static int 1599 test21(int fd) 1600 { 1601 struct flock fl; 1602 int res; 1603 1604 fl.l_start = 0; 1605 fl.l_len = 100; 1606 fl.l_pid = 0; 1607 fl.l_type = F_WRLCK; 1608 fl.l_whence = 0; 1609 res = fcntl(fd, F_SETLK, &fl); 1610 FAIL(res != 0); 1611 1612 fl.l_start = 50; 1613 fl.l_len = 100; 1614 fl.l_pid = 0; 1615 fl.l_type = F_WRLCK; 1616 fl.l_whence = 0; 1617 res = fcntl(fd, F_SETLK, &fl); 1618 FAIL(res != 0); 1619 1620 SUCCEED; 1621 } 1622 1623 /* 1624 * Test 22 - lf_findoverlap() case 5 1625 * 1626 * Overlap ends after lock. 1627 */ 1628 static int 1629 test22(int fd) 1630 { 1631 struct flock fl; 1632 int res; 1633 1634 fl.l_start = 10; 1635 fl.l_len = 100; 1636 fl.l_pid = 0; 1637 fl.l_type = F_WRLCK; 1638 fl.l_whence = 0; 1639 res = fcntl(fd, F_SETLK, &fl); 1640 FAIL(res != 0); 1641 1642 fl.l_start = 0; 1643 fl.l_len = 50; 1644 fl.l_pid = 0; 1645 fl.l_type = F_WRLCK; 1646 fl.l_whence = 0; 1647 res = fcntl(fd, F_SETLK, &fl); 1648 FAIL(res != 0); 1649 1650 SUCCEED; 1651 } 1652 1653 /* 1654 * Test 23 - positive length overflow 1655 */ 1656 static int 1657 test23(int fd) 1658 { 1659 struct flock fl; 1660 int res; 1661 1662 fl.l_pid = 0; 1663 fl.l_type = F_WRLCK; 1664 fl.l_whence = SEEK_SET; 1665 fl.l_start = 2; 1666 fl.l_len = LLONG_MAX; 1667 res = fcntl(fd, F_SETLK, &fl); 1668 FAIL(res != -1); 1669 FAIL(errno != EOVERFLOW); 1670 1671 SUCCEED; 1672 } 1673 1674 /* 1675 * Test 24 - negative length 1676 */ 1677 static int 1678 test24(int fd) 1679 { 1680 struct flock fl; 1681 pid_t pid; 1682 int res, status; 1683 1684 fl.l_pid = 0; 1685 fl.l_type = F_WRLCK; 1686 fl.l_whence = SEEK_SET; 1687 1688 /* Start offset plus length must be positive. */ 1689 fl.l_start = 0; 1690 fl.l_len = LLONG_MIN; 1691 res = fcntl(fd, F_SETLK, &fl); 1692 FAIL(res != -1); 1693 FAIL(errno != EINVAL); 1694 1695 /* Set exclusive lock on range [2,3] */ 1696 fl.l_start = 4; 1697 fl.l_len = -2; 1698 res = fcntl(fd, F_SETLK, &fl); 1699 FAIL(res != 0); 1700 1701 /* Another process must not be able to lock the same range. */ 1702 pid = fork(); 1703 if (pid == -1) 1704 err(1, "fork"); 1705 if (pid == 0) { 1706 fl.l_start = 2; 1707 fl.l_len = 2; 1708 res = fcntl(fd, F_GETLK, &fl); 1709 FAIL(res != 0); 1710 FAIL(fl.l_type == F_UNLCK); 1711 _exit(0); 1712 } 1713 status = safe_waitpid(pid); 1714 FAIL(status != 0); 1715 1716 SUCCEED; 1717 } 1718 1719 /* 1720 * Test 25 - use after free regression 1721 * 1722 * Discovered by syzkaller. 1723 */ 1724 static int 1725 test25(int fd) 1726 { 1727 struct flock fl; 1728 int master, res, slave; 1729 1730 res = openpty(&master, &slave, NULL, NULL, NULL); 1731 FAIL(res == -1); 1732 close(master); 1733 1734 fl.l_start = 0; 1735 fl.l_len = 0; 1736 fl.l_pid = 0; 1737 fl.l_type = F_RDLCK; 1738 fl.l_whence = SEEK_SET; 1739 res = fcntl(slave, F_SETLKW, &fl); 1740 FAIL(res != 0); 1741 1742 fl.l_start = 3; 1743 fl.l_len = 0x7ffffffffffffffd; 1744 fl.l_pid = 0; 1745 fl.l_type = F_UNLCK; 1746 fl.l_whence = SEEK_END; 1747 res = fcntl(slave, F_SETLKW, &fl); 1748 FAIL(res != 0); 1749 1750 fl.l_start = 0; 1751 fl.l_len = 0; 1752 fl.l_pid = 0; 1753 fl.l_type = F_RDLCK; 1754 fl.l_whence = SEEK_SET; 1755 res = fcntl(slave, F_SETLKW, &fl); 1756 FAIL(res != 0); 1757 1758 close(slave); 1759 1760 SUCCEED; 1761 } 1762 1763 /* 1764 * Test 26 - range end point ambiguity regression 1765 * 1766 * When a new lock range [start, LLONG_MAX] overlapped with an existing range, 1767 * kernel's lock data structure could become inconsistent. 1768 */ 1769 static int 1770 test26(int fd) 1771 { 1772 struct flock fl; 1773 pid_t pid; 1774 int res, status; 1775 1776 /* Lock the whole range. */ 1777 fl.l_start = 0; 1778 fl.l_len = 0; 1779 fl.l_pid = 0; 1780 fl.l_type = F_RDLCK; 1781 fl.l_whence = SEEK_SET; 1782 res = fcntl(fd, F_SETLK, &fl); 1783 FAIL(res != 0); 1784 1785 /* 1786 * Split the range at the end. 1787 * This should be handled as if l_len == 0. 1788 */ 1789 fl.l_start = LLONG_MAX; 1790 fl.l_len = 1; 1791 fl.l_pid = 0; 1792 fl.l_type = F_WRLCK; 1793 fl.l_whence = SEEK_SET; 1794 res = fcntl(fd, F_SETLK, &fl); 1795 FAIL(res != 0); 1796 1797 /* Check the resulting ranges. */ 1798 pid = fork(); 1799 if (pid == -1) 1800 err(1, "fork"); 1801 if (pid == 0) { 1802 fl.l_start = 0; 1803 fl.l_len = 0; 1804 fl.l_type = F_WRLCK; 1805 fl.l_whence = SEEK_SET; 1806 res = fcntl(fd, F_GETLK, &fl); 1807 FAIL(res != 0); 1808 FAIL(fl.l_type != F_RDLCK); 1809 FAIL(fl.l_start != 0); 1810 FAIL(fl.l_len != LLONG_MAX); 1811 1812 fl.l_start = LLONG_MAX; 1813 fl.l_len = 0; 1814 fl.l_type = F_WRLCK; 1815 fl.l_whence = SEEK_SET; 1816 res = fcntl(fd, F_GETLK, &fl); 1817 FAIL(res != 0); 1818 FAIL(fl.l_type != F_WRLCK); 1819 FAIL(fl.l_start != LLONG_MAX); 1820 FAIL(fl.l_len != 0); 1821 1822 _exit(0); 1823 } 1824 status = safe_waitpid(pid); 1825 FAIL(status != 0); 1826 1827 /* Release all locks. */ 1828 fl.l_start = 0; 1829 fl.l_len = 0; 1830 fl.l_pid = 0; 1831 fl.l_type = F_UNLCK; 1832 fl.l_whence = SEEK_SET; 1833 res = fcntl(fd, F_SETLK, &fl); 1834 FAIL(res != 0); 1835 1836 /* Check the resulting ranges. */ 1837 pid = fork(); 1838 if (pid == -1) 1839 err(1, "fork"); 1840 if (pid == 0) { 1841 fl.l_start = 0; 1842 fl.l_len = 0; 1843 fl.l_type = F_WRLCK; 1844 fl.l_whence = SEEK_SET; 1845 res = fcntl(fd, F_GETLK, &fl); 1846 FAIL(res != 0); 1847 FAIL(fl.l_type != F_UNLCK); 1848 FAIL(fl.l_start != 0); 1849 FAIL(fl.l_len != 0); 1850 1851 _exit(0); 1852 } 1853 status = safe_waitpid(pid); 1854 FAIL(status != 0); 1855 1856 SUCCEED; 1857 } 1858 1859 static struct test tests[] = { 1860 { test1, 0 }, 1861 { test2, 0 }, 1862 { test3, 1 }, 1863 { test4, 0 }, 1864 { test5, 1 }, 1865 { test6, 1 }, 1866 { test7, 0 }, 1867 { test8, 0 }, 1868 { test9, 0 }, 1869 { test10, 0 }, 1870 { test11, 1 }, 1871 { test12, 0 }, 1872 { test13, 1 }, 1873 { test14, 0 }, 1874 { test15, 1 }, 1875 { test16, 0 }, 1876 { test17, 0 }, 1877 { test18, 0 }, 1878 { test19, 0 }, 1879 { test20, 0 }, 1880 { test21, 0 }, 1881 { test22, 0 }, 1882 { test23, 0 }, 1883 { test24, 0 }, 1884 { test25, 0 }, 1885 { test26, 0 }, 1886 }; 1887 1888 static int test_count = sizeof(tests) / sizeof(tests[0]); 1889 1890 int 1891 main(int argc, char *argv[]) 1892 { 1893 struct sigaction sa; 1894 const char *errstr; 1895 int c, fd, i; 1896 int error = 0; 1897 int testnum = 0; 1898 1899 while ((c = getopt(argc, argv, "v")) != -1) 1900 switch (c) { 1901 case 'v': 1902 verbose = 1; 1903 break; 1904 default: 1905 usage(); 1906 } 1907 argc -= optind; 1908 argv += optind; 1909 if (argc > 1) 1910 usage(); 1911 if (argc == 1) { 1912 testnum = strtonum(argv[0], 1, test_count, &errstr); 1913 if (testnum == 0) 1914 errx(1, "test number %s", errstr); 1915 } 1916 1917 fd = make_file(1024); 1918 1919 sa.sa_handler = ignore_alarm; 1920 sigemptyset(&sa.sa_mask); 1921 sa.sa_flags = 0; 1922 sigaction(SIGALRM, &sa, 0); 1923 1924 for (i = 0; i < test_count; i++) { 1925 if (testnum == 0 || testnum == i + 1) 1926 error |= tests[i].testfn(fd); 1927 } 1928 1929 return (error ? 1 : 0); 1930 } 1931