1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) International Business Machines Corp., 2002
4 * Author: Cyril Hrubis
5 *
6 * Test Description:
7 * This test verifies that flock() cannot unlock a file locked by another
8 * task.
9 *
10 * Test Steps:
11 * Fork a child processes The parent flocks a file with LOCK_EX Child waits
12 * for that to happen, then checks to make sure it is locked. Child then
13 * tries to unlock the file. If the unlock succeeds, the child attempts to
14 * lock the file with LOCK_EX. The test passes if the child is able to lock
15 * the file.
16 */
17
18 #include <errno.h>
19 #include <stdlib.h>
20 #include <sys/file.h>
21
22 #include "tst_test.h"
23
childfunc(int fd)24 static void childfunc(int fd)
25 {
26 int fd2;
27 TST_CHECKPOINT_WAIT(0);
28
29 fd2 = SAFE_OPEN("testfile", O_RDWR);
30 if (flock(fd2, LOCK_EX | LOCK_NB) != -1)
31 tst_brk(TBROK, "CHILD: The file was not already locked");
32
33 TEST(flock(fd, LOCK_UN));
34 if (TST_RET == -1) {
35 tst_res(TFAIL, "CHILD: Unable to unlock file locked by "
36 "parent: %s", tst_strerrno(TST_ERR));
37 exit(1);
38 } else {
39 tst_res(TPASS, "CHILD: File locked by parent unlocked");
40 }
41
42 TEST(flock(fd2, LOCK_EX | LOCK_NB));
43 if (TST_RET == -1) {
44 tst_res(TFAIL, "CHILD: Unable to unlock file after "
45 "unlocking: %s", tst_strerrno(TST_ERR));
46 exit(1);
47 } else {
48 tst_res(TPASS, "Locking after unlock passed");
49 }
50
51 SAFE_CLOSE(fd);
52 SAFE_CLOSE(fd2);
53
54 exit(0);
55 }
56
verify_flock(void)57 static void verify_flock(void)
58 {
59 int fd1;
60 pid_t pid;
61
62 fd1 = SAFE_OPEN("testfile", O_RDWR);
63
64 pid = SAFE_FORK();
65 if (pid == 0)
66 childfunc(fd1);
67
68 TEST(flock(fd1, LOCK_EX | LOCK_NB));
69 if (TST_RET != 0) {
70 tst_res(TFAIL | TTERRNO,
71 "Parent: Initial attempt to flock() failed");
72 } else {
73 tst_res(TPASS,
74 "Parent: Initial attempt to flock() passed");
75 }
76
77 TST_CHECKPOINT_WAKE(0);
78
79 tst_reap_children();
80
81 SAFE_CLOSE(fd1);
82 }
83
setup(void)84 static void setup(void)
85 {
86 int fd;
87
88 fd = SAFE_OPEN("testfile", O_CREAT | O_TRUNC | O_RDWR, 0666);
89 SAFE_CLOSE(fd);
90 }
91
92 static struct tst_test test = {
93 .test_all = verify_flock,
94 .needs_checkpoints = 1,
95 .forks_child = 1,
96 .setup = setup,
97 };
98