|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
1 | 2 | /*
|
2 |
| - * Copyright (c) International Business Machines Corp., 2006 |
3 |
| - * AUTHOR: Yi Yang <[email protected]> |
4 |
| - * |
5 |
| - * This program is free software; you can redistribute it and/or modify |
6 |
| - * it under the terms of the GNU General Public License as published by |
7 |
| - * the Free Software Foundation; either version 2 of the License, or |
8 |
| - * (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 |
13 |
| - * the 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, write to the Free Software Foundation, |
17 |
| - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 3 | + * Copyright (c) International Business Machines Corp., 2006 |
| 4 | + * Copyright (c) Linux Test Project, 2007-2025 |
18 | 5 | */
|
19 |
| -/* |
20 |
| - * DESCRIPTION |
21 |
| - * This test case will verify basic function of fchownat |
22 |
| - * added by kernel 2.6.16 or up. |
| 6 | + |
| 7 | +/*\ |
| 8 | + * [Description] |
| 9 | + * |
| 10 | + * Verify that fchownat() succeeds to change file's ownership if the file |
| 11 | + * descriptor is AT_FDCWD or set by opening a directory. |
23 | 12 | */
|
24 | 13 |
|
25 | 14 | #define _GNU_SOURCE
|
| 15 | +#include "tst_test.h" |
26 | 16 |
|
27 |
| -#include <sys/types.h> |
28 |
| -#include <sys/stat.h> |
29 |
| -#include <unistd.h> |
30 |
| -#include <stdlib.h> |
31 |
| -#include <errno.h> |
32 |
| -#include <string.h> |
33 |
| -#include <signal.h> |
34 |
| - |
35 |
| -#include "test.h" |
36 |
| -#include "safe_macros.h" |
37 |
| -#include "lapi/fcntl.h" |
| 17 | +#define TESTFILE1 "testfile1" |
| 18 | +#define TESTFILE2 "testfile2" |
38 | 19 |
|
39 |
| -#define TESTFILE "testfile" |
| 20 | +static uid_t set_uid = 1000; |
| 21 | +static gid_t set_gid = 1000; |
| 22 | +static int dir_fd = -1; |
40 | 23 |
|
41 |
| -static void setup(void); |
42 |
| -static void cleanup(void); |
43 |
| - |
44 |
| -static int dir_fd; |
45 |
| -static int fd; |
46 |
| -static int no_fd = -1; |
47 |
| -static int cu_fd = AT_FDCWD; |
48 |
| - |
49 |
| -static struct test_case_t { |
50 |
| - int exp_ret; |
51 |
| - int exp_errno; |
52 |
| - int flag; |
53 |
| - int *fds; |
54 |
| - char *filenames; |
55 |
| -} test_cases[] = { |
56 |
| - {0, 0, 0, &dir_fd, TESTFILE}, |
57 |
| - {-1, ENOTDIR, 0, &fd, TESTFILE}, |
58 |
| - {-1, EBADF, 0, &no_fd, TESTFILE}, |
59 |
| - {-1, EINVAL, 9999, &dir_fd, TESTFILE}, |
60 |
| - {0, 0, 0, &cu_fd, TESTFILE}, |
61 |
| -}; |
62 |
| - |
63 |
| -char *TCID = "fchownat01"; |
64 |
| -int TST_TOTAL = ARRAY_SIZE(test_cases); |
65 |
| -static void fchownat_verify(const struct test_case_t *); |
66 |
| - |
67 |
| -int main(int ac, char **av) |
| 24 | +static void fchownat_verify(void) |
68 | 25 | {
|
69 |
| - int lc; |
70 |
| - int i; |
| 26 | + struct stat stat_buf; |
71 | 27 |
|
72 |
| - tst_parse_opts(ac, av, NULL, NULL); |
| 28 | + TST_EXP_PASS(fchownat(AT_FDCWD, TESTFILE1, set_uid, set_gid, 0), |
| 29 | + "fchownat(%d, %s, %d, %d, 0)", |
| 30 | + AT_FDCWD, TESTFILE1, set_uid, set_gid); |
73 | 31 |
|
74 |
| - setup(); |
| 32 | + SAFE_STAT(TESTFILE1, &stat_buf); |
| 33 | + TST_EXP_EQ_LI(stat_buf.st_uid, set_uid); |
| 34 | + TST_EXP_EQ_LI(stat_buf.st_gid, set_gid); |
75 | 35 |
|
76 |
| - for (lc = 0; TEST_LOOPING(lc); lc++) { |
77 |
| - tst_count = 0; |
78 |
| - for (i = 0; i < TST_TOTAL; i++) |
79 |
| - fchownat_verify(&test_cases[i]); |
80 |
| - } |
| 36 | + TST_EXP_PASS(fchownat(dir_fd, TESTFILE2, set_uid, set_gid, 0), |
| 37 | + "fchownat(%d, %s, %d, %d, 0)", |
| 38 | + dir_fd, TESTFILE2, set_uid, set_gid); |
81 | 39 |
|
82 |
| - cleanup(); |
83 |
| - tst_exit(); |
| 40 | + SAFE_STAT(TESTFILE2, &stat_buf); |
| 41 | + TST_EXP_EQ_LI(stat_buf.st_uid, set_uid); |
| 42 | + TST_EXP_EQ_LI(stat_buf.st_gid, set_gid); |
84 | 43 | }
|
85 | 44 |
|
86 | 45 | static void setup(void)
|
87 | 46 | {
|
88 |
| - tst_sig(NOFORK, DEF_HANDLER, cleanup); |
89 |
| - |
90 |
| - TEST_PAUSE; |
91 |
| - |
92 |
| - tst_tmpdir(); |
93 |
| - |
94 |
| - dir_fd = SAFE_OPEN(cleanup, "./", O_DIRECTORY); |
95 |
| - |
96 |
| - SAFE_TOUCH(cleanup, TESTFILE, 0600, NULL); |
97 |
| - |
98 |
| - fd = SAFE_OPEN(cleanup, "testfile2", O_CREAT | O_RDWR, 0600); |
99 |
| -} |
100 |
| - |
101 |
| -static void fchownat_verify(const struct test_case_t *test) |
102 |
| -{ |
103 |
| - TEST(fchownat(*(test->fds), test->filenames, geteuid(), |
104 |
| - getegid(), test->flag)); |
105 |
| - |
106 |
| - if (TEST_RETURN != test->exp_ret) { |
107 |
| - tst_resm(TFAIL | TTERRNO, |
108 |
| - "fchownat() returned %ld, expected %d, errno=%d", |
109 |
| - TEST_RETURN, test->exp_ret, test->exp_errno); |
110 |
| - return; |
111 |
| - } |
112 |
| - |
113 |
| - if (TEST_ERRNO == test->exp_errno) { |
114 |
| - tst_resm(TPASS | TTERRNO, |
115 |
| - "fchownat() returned the expected errno %d: %s", |
116 |
| - test->exp_ret, strerror(test->exp_errno)); |
117 |
| - } else { |
118 |
| - tst_resm(TFAIL | TTERRNO, |
119 |
| - "fchownat() failed unexpectedly; expected: %d - %s", |
120 |
| - test->exp_errno, strerror(test->exp_errno)); |
121 |
| - } |
| 47 | + dir_fd = SAFE_OPEN("./", O_DIRECTORY); |
| 48 | + SAFE_TOUCH(TESTFILE1, 0600, NULL); |
| 49 | + SAFE_TOUCH(TESTFILE2, 0600, NULL); |
122 | 50 | }
|
123 | 51 |
|
124 | 52 | static void cleanup(void)
|
125 | 53 | {
|
126 |
| - if (fd > 0) |
127 |
| - close(fd); |
128 |
| - |
129 |
| - if (dir_fd > 0) |
130 |
| - close(dir_fd); |
131 |
| - |
132 |
| - tst_rmdir(); |
| 54 | + if (dir_fd != -1) |
| 55 | + SAFE_CLOSE(dir_fd); |
133 | 56 | }
|
| 57 | + |
| 58 | +static struct tst_test test = { |
| 59 | + .needs_tmpdir = 1, |
| 60 | + .needs_root = 1, |
| 61 | + .test_all = fchownat_verify, |
| 62 | + .setup = setup, |
| 63 | + .cleanup = cleanup, |
| 64 | +}; |
0 commit comments