]>
Commit | Line | Data |
---|---|---|
06ab719d AZ |
1 | /* Check non representable OFD locks regions in non-LFS mode for compat |
2 | mode (BZ #20251) | |
04277e02 | 3 | Copyright (C) 2018-2019 Free Software Foundation, Inc. |
06ab719d AZ |
4 | |
5 | This program is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU General Public License | |
7 | as published by the Free Software Foundation; either version 2 | |
8 | of the License, or (at your option) any later version. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with this program; if not, see <http://www.gnu.org/licenses/>. | |
17 | */ | |
18 | ||
19 | #include <unistd.h> | |
20 | #include <fcntl.h> | |
21 | #include <stdint.h> | |
22 | #include <errno.h> | |
23 | ||
24 | #include <support/temp_file.h> | |
25 | #include <support/check.h> | |
26 | ||
27 | #include <shlib-compat.h> | |
28 | #if TEST_COMPAT (libc, GLIBC_2_0, GLIBC_2_28) | |
29 | compat_symbol_reference (libc, fcntl, fcntl, GLIBC_2_0); | |
30 | ||
31 | static char *temp_filename; | |
32 | static int temp_fd; | |
33 | ||
34 | static void | |
35 | do_prepare (int argc, char **argv) | |
36 | { | |
37 | temp_fd = create_temp_file ("tst-ofdlocks-compat.", &temp_filename); | |
38 | TEST_VERIFY_EXIT (temp_fd != -1); | |
39 | } | |
40 | ||
41 | #define PREPARE do_prepare | |
42 | ||
b444e8f7 AZ |
43 | /* Linux between 4.13 and 4.15 return EOVERFLOW for LFS OFD locks usage |
44 | in compat mode (non-LFS ABI running on a LFS default kernel, such as | |
45 | i386 on a x86_64 kernel or s390-32 on a s390-64 kernel) [1]. This is | |
46 | a kernel issue because __NR_fcntl64 is the expected way to use OFD locks | |
47 | (used on GLIBC for both fcntl and fcntl64). | |
48 | ||
49 | [1] https://sourceware.org/ml/libc-alpha/2018-07/msg00243.html */ | |
50 | ||
06ab719d AZ |
51 | static int |
52 | do_test (void) | |
53 | { | |
54 | /* The compat fcntl version for architectures which support non-LFS | |
55 | operations does not wrap the flock OFD argument, so the struct is passed | |
56 | unmodified to kernel. It means no EOVERFLOW is returned, so operations | |
57 | with LFS should not incur in failure. */ | |
58 | ||
59 | struct flock64 lck64 = { | |
60 | .l_type = F_WRLCK, | |
61 | .l_whence = SEEK_SET, | |
62 | .l_start = (off64_t)INT32_MAX + 1024, | |
63 | .l_len = 1024, | |
64 | }; | |
2c6da2f4 AZ |
65 | int ret = fcntl (temp_fd, F_OFD_SETLKW, &lck64); |
66 | if (ret == -1 && errno == EINVAL) | |
67 | /* OFD locks are only available on Linux 3.15. */ | |
68 | FAIL_UNSUPPORTED ("fcntl (F_OFD_SETLKW) not supported"); | |
69 | ||
70 | TEST_VERIFY_EXIT (ret == 0); | |
06ab719d AZ |
71 | |
72 | /* Open file description locks placed through the same open file description | |
73 | (either by same file descriptor or a duplicated one created by fork, | |
74 | dup, fcntl F_DUPFD, etc.) overwrites then old lock. To force a | |
75 | conflicting lock combination, it creates a new file descriptor. */ | |
76 | int fd = open64 (temp_filename, O_RDWR, 0666); | |
77 | TEST_VERIFY_EXIT (fd != -1); | |
78 | ||
79 | struct flock64 lck = { | |
80 | .l_type = F_WRLCK, | |
81 | .l_whence = SEEK_SET, | |
82 | .l_start = INT32_MAX - 1024, | |
83 | .l_len = 4 * 1024, | |
84 | }; | |
85 | TEST_VERIFY (fcntl (fd, F_OFD_GETLK, &lck) == 0); | |
86 | ||
87 | return 0; | |
88 | } | |
89 | #else | |
90 | static int | |
91 | do_test (void) | |
92 | { | |
93 | return 77; | |
94 | } | |
95 | #endif | |
96 | ||
97 | #include <support/test-driver.c> |