xref: /openbsd/regress/sys/kern/flock/flock.c (revision c3602110)
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
ignore_alarm(int __unused sig)50 ignore_alarm(int __unused sig)
51 {
52 }
53 
54 static int
safe_kill(pid_t pid,int sig)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
test1(int fd)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
test2(int fd)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
test3(int fd)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
test4(int fd)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
test5(int fd)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
test6(int fd)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
test7(int fd)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
test8(int fd)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
test9(int fd)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
test10(int fd)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
test11(int fd)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
test12(int fd)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
test13(int fd)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
test14(int fd)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
test15(int fd)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
test16(int fd)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
test17(int fd)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
test18(int fd)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
test19(int fd)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
test20(int fd)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
test21(int fd)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
test22(int fd)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
test23(int fd)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
test24(int fd)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
test25(int fd)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
test26(int fd)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
main(int argc,char * argv[])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