1 /*
2 * Copyright (C) 2024 HiHope Open Source Organization.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <cerrno>
17 #include <cstdio>
18 #include <cstdlib>
19 #include <string>
20 #include <vector>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <gtest/gtest.h>
24 #include <sys/file.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include "securec.h"
28
29 using namespace testing::ext;
30 using namespace std;
31
32 static const int PATH_MAX_LEN = 128;
33 static const char *TEST_FILE = "/data/local/tmp/fchownat.txt";
34 static const char *TEST_FILE_PATH = "/data/local/tmp";
35 static const char *TEST_FILE_NAME = "fchownat.txt";
36 static const char *SYMBOL_LINK_NAME = "TestFchmodatSymlink";
37 mode_t MODE_0644 = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
38 mode_t MODE_0755 = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
39
40 class FchownatApiTest : public testing::Test {
41 public:
42 static void SetUpTestCase();
43 static void TearDownTestCase();
44 void SetUp();
45 void TearDown();
46 private:
47 };
SetUp()48 void FchownatApiTest::SetUp()
49 {
50 }
TearDown()51 void FchownatApiTest::TearDown()
52 {
53 }
SetUpTestCase()54 void FchownatApiTest::SetUpTestCase()
55 {
56 }
TearDownTestCase()57 void FchownatApiTest::TearDownTestCase()
58 {
59 }
60
61 /*
62 * @tc.number : SUB_KERNEL_SYSCALL_FCHOWNAT_0100
63 * @tc.name : FchownatFileSuccess_0001
64 * @tc.desc : fchownat change specify path file owner id and group id success.
65 * @tc.size : MediumTest
66 * @tc.type : Function
67 * @tc.level : Level 1
68 */
HWTEST_F(FchownatApiTest, FchownatFileSuccess_0001, Function | MediumTest | Level1)69 HWTEST_F(FchownatApiTest, FchownatFileSuccess_0001, Function | MediumTest | Level1)
70 {
71 int ret = -1;
72 struct stat stat1;
73 struct stat stat2;
74
75 int dirfd = open(TEST_FILE_PATH, O_RDONLY | O_DIRECTORY);
76 EXPECT_TRUE(dirfd > 0);
77
78 int fd = open(TEST_FILE, O_RDWR | O_CREAT, MODE_0755);
79 EXPECT_TRUE(fd > 0);
80 ret = fstat(fd, &stat1);
81 EXPECT_EQ(ret, 0);
82 uid_t uid = stat1.st_uid + 1;
83 gid_t gid = stat1.st_gid + 1;
84
85 ret = fchownat(dirfd, TEST_FILE_NAME, uid, gid, 0);
86 EXPECT_EQ(ret, 0);
87 ret = fstat(fd, &stat2);
88 EXPECT_EQ(stat2.st_uid, uid);
89 EXPECT_EQ(stat2.st_gid, gid);
90
91 close(dirfd);
92 close(fd);
93 remove(TEST_FILE);
94 }
95
96 /*
97 * @tc.number : SUB_KERNEL_SYSCALL_FCHOWNAT_0200
98 * @tc.name : FchownatAT_FDCWDTestSuccess_0002
99 * @tc.desc : fchownat change current path file owner id and group id by AT_FDCWD success.
100 * @tc.size : MediumTest
101 * @tc.type : Function
102 * @tc.level : Level 1
103 */
HWTEST_F(FchownatApiTest, FchownatAT_FDCWDTestSuccess_0002, Function | MediumTest | Level1)104 HWTEST_F(FchownatApiTest, FchownatAT_FDCWDTestSuccess_0002, Function | MediumTest | Level1)
105 {
106 int ret = -1;
107 char path[PATH_MAX_LEN];
108 struct stat stat1;
109 struct stat stat2;
110 int fd = 0;
111
112 char *dir = getcwd(path, sizeof(path));
113 EXPECT_NE(dir, nullptr);
114 ret = chdir(TEST_FILE_PATH);
115 EXPECT_EQ(ret, 0);
116 if (access(TEST_FILE_NAME, F_OK) == -1) {
117 fd = open(TEST_FILE_NAME, O_RDWR | O_CREAT, MODE_0644);
118 }
119
120 ret = fstat(fd, &stat1);
121 EXPECT_EQ(ret, 0);
122 uid_t uid = stat1.st_uid + 1;
123 gid_t gid = stat1.st_gid + 1;
124
125 ret = fchownat(AT_FDCWD, TEST_FILE_NAME, uid, gid, 0);
126 EXPECT_EQ(ret, 0);
127 ret = fstat(fd, &stat2);
128 EXPECT_EQ(stat2.st_uid, uid);
129 EXPECT_EQ(stat2.st_gid, gid);
130
131 chdir(path);
132 close(fd);
133 remove(TEST_FILE);
134 }
135
136 /*
137 * @tc.number : SUB_KERNEL_SYSCALL_FCHOWNAT_0300
138 * @tc.name : FchownatInvalidFdFail_0003
139 * @tc.desc : fchownat change invalid file owner id and group id fail, errno EBADF.
140 * @tc.size : MediumTest
141 * @tc.type : Function
142 * @tc.level : Level 2
143 */
HWTEST_F(FchownatApiTest, FchownatInvalidFdFail_0003, Function | MediumTest | Level2)144 HWTEST_F(FchownatApiTest, FchownatInvalidFdFail_0003, Function | MediumTest | Level2)
145 {
146 int invalidFd = -1;
147 errno = 0;
148 int ret = fchownat(invalidFd, TEST_FILE_NAME, 1, 1, 0);
149 EXPECT_NE(ret, 0);
150 EXPECT_EQ(errno, EBADF);
151 }
152
153 /*
154 * @tc.number : SUB_KERNEL_SYSCALL_FCHOWNAT_0400
155 * @tc.name : FchownatLinkFileTestSuccess_0004
156 * @tc.desc : fchownat change file owner id and group id by file link success.
157 * @tc.size : MediumTest
158 * @tc.type : Function
159 * @tc.level : Level 1
160 */
HWTEST_F(FchownatApiTest, FchownatLinkFileTestSuccess_0004, Function | MediumTest | Level1)161 HWTEST_F(FchownatApiTest, FchownatLinkFileTestSuccess_0004, Function | MediumTest | Level1)
162 {
163 int ret = -1;
164 struct stat stat1;
165 struct stat stat2;
166 char path[PATH_MAX_LEN];
167 char *dir = getcwd(path, sizeof(path));
168 EXPECT_NE(dir, nullptr);
169 ret = chdir(TEST_FILE_PATH);
170 EXPECT_EQ(ret, 0);
171
172 int fd = open(TEST_FILE, O_RDWR | O_CREAT, MODE_0755);
173 EXPECT_TRUE(fd > 0);
174 ret = fstat(fd, &stat1);
175 EXPECT_EQ(ret, 0);
176 uid_t uid = stat1.st_uid + 1;
177 gid_t gid = stat1.st_gid + 1;
178
179 ret = symlink(TEST_FILE_NAME, SYMBOL_LINK_NAME);
180 EXPECT_EQ(ret, 0);
181
182 ret = fchownat(AT_FDCWD, SYMBOL_LINK_NAME, uid, gid, 0);
183 EXPECT_EQ(ret, 0);
184 ret = fstat(fd, &stat2);
185 EXPECT_EQ(ret, 0);
186 EXPECT_EQ(stat2.st_uid, uid);
187 EXPECT_EQ(stat2.st_gid, gid);
188
189 unlink(TEST_FILE_NAME);
190 close(fd);
191 remove(TEST_FILE);
192 remove(SYMBOL_LINK_NAME);
193 chdir(path);
194 }
195
196 /*
197 * @tc.number : SUB_KERNEL_SYSCALL_FCHOWNAT_0500
198 * @tc.name : FchownatAT_SYMLINK_NOFOLLOWTestSuccess_0005
199 * @tc.desc : fchownat change owner id and group id of file link itself success.
200 * @tc.size : MediumTest
201 * @tc.type : Function
202 * @tc.level : Level 1
203 */
HWTEST_F(FchownatApiTest, FchownatAT_SYMLINK_NOFOLLOWTestSuccess_0005, Function | MediumTest | Level1)204 HWTEST_F(FchownatApiTest, FchownatAT_SYMLINK_NOFOLLOWTestSuccess_0005, Function | MediumTest | Level1)
205 {
206 int ret = -1;
207 struct stat stat1;
208 struct stat stat2;
209 char path[PATH_MAX_LEN];
210 char *dir = getcwd(path, sizeof(path));
211 EXPECT_NE(dir, nullptr);
212 ret = chdir(TEST_FILE_PATH);
213 EXPECT_EQ(ret, 0);
214
215 int fd = open(TEST_FILE_NAME, O_RDWR | O_CREAT, MODE_0644);
216 EXPECT_TRUE(fd > 0);
217 ret = symlink(TEST_FILE_NAME, SYMBOL_LINK_NAME);
218 EXPECT_EQ(ret, 0);
219
220 ret = fstat(fd, &stat1);
221 EXPECT_EQ(ret, 0);
222 uid_t uid = stat1.st_uid + 1;
223 gid_t gid = stat1.st_gid + 1;
224
225 ret = fchownat(AT_FDCWD, SYMBOL_LINK_NAME, uid, gid, AT_SYMLINK_NOFOLLOW);
226 EXPECT_EQ(ret, 0);
227 ret = fstat(fd, &stat2);
228 EXPECT_EQ(ret, 0);
229 EXPECT_NE(stat2.st_uid, uid);
230 EXPECT_NE(stat2.st_gid, gid);
231
232 unlink(TEST_FILE_NAME);
233 close(fd);
234 remove(TEST_FILE);
235 remove(SYMBOL_LINK_NAME);
236 chdir(path);
237 }
238
239 /*
240 * @tc.number : SUB_KERNEL_SYSCALL_FCHOWNAT_0600
241 * @tc.name : FchownatAT_EMPTY_PATHTestSuccess_0006
242 * @tc.desc : fchownat change current path file owner id and group id by AT_EMPTY_PATH success.
243 * @tc.size : MediumTest
244 * @tc.type : Function
245 * @tc.level : Level 1
246 */
HWTEST_F(FchownatApiTest, FchownatAT_EMPTY_PATHTestSuccess_0006, Function | MediumTest | Level1)247 HWTEST_F(FchownatApiTest, FchownatAT_EMPTY_PATHTestSuccess_0006, Function | MediumTest | Level1)
248 {
249 int ret = -1;
250 struct stat stat1;
251
252 int fd = open(TEST_FILE, O_RDWR | O_CREAT, 0644);
253 EXPECT_TRUE(fd > 0);
254
255 ret = fstat(fd, &stat1);
256 EXPECT_EQ(ret, 0);
257 uid_t uid = stat1.st_uid + 1;
258 gid_t gid = stat1.st_gid + 1;
259
260 ret = fchownat(fd, "", uid, gid, AT_EMPTY_PATH);
261 EXPECT_EQ(ret, 0);
262
263 close(fd);
264 remove(TEST_FILE);
265 }
266