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
33 static const int PATH_MAX_LEN = 128;
34 static const char *TEST_FILE = "/data/local/tmp/test.txt";
35 static const char *TEST_FILE_PATH = "/data/local/tmp";
36 static const char *TEST_FILE_NAME = "test.txt";
37 static const char *SYMBOL_LINK_NAME = "TestSymlink";
38 mode_t MODE_0600 = S_IRUSR | S_IWUSR;
39 mode_t MODE_0644 = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
40 mode_t MODE_0755 = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
41 struct stat g_statbuf;
42
43 class FchmodatApiTest : public testing::Test {
44 public:
45 static void SetUpTestCase();
46 static void TearDownTestCase();
47 void SetUp();
48 void TearDown();
49 private:
50 };
51
SetUp()52 void FchmodatApiTest::SetUp()
53 {
54 }
TearDown()55 void FchmodatApiTest::TearDown()
56 {
57 }
SetUpTestCase()58 void FchmodatApiTest::SetUpTestCase()
59 {
60 }
TearDownTestCase()61 void FchmodatApiTest::TearDownTestCase()
62 {
63 unlink(TEST_FILE);
64 }
65
66
67 /*
68 * @tc.number : SUB_KERNEL_SYSCALL_FCHMODAT_0100
69 * @tc.name : FchmodatFileModeSuccess_0001
70 * @tc.desc : fchmodat valid file mode bits success.
71 * @tc.size : MediumTest
72 * @tc.type : Function
73 * @tc.level : Level 1
74 */
75 HWTEST_F(FchmodatApiTest, FchmodatFileModeSuccess_0001, Function | MediumTest | Level1)
76 {
77 int ret = -1;
78 if (access(TEST_FILE_PATH, F_OK) != 0) {
79 ret = mkdir(TEST_FILE_PATH, MODE_0644);
80 EXPECT_EQ(ret, 0);
81 }
82 char path[PATH_MAX_LEN];
83 char *dir = getcwd(path, sizeof(path));
84 EXPECT_NE(dir, nullptr);
85 ret = chdir(TEST_FILE_PATH);
86 EXPECT_EQ(ret, 0);
87 if (access(TEST_FILE_NAME, F_OK) == -1) {
88 FILE *fp = fopen(TEST_FILE_NAME, "w");
89 EXPECT_NE(fp, nullptr);
90 fclose(fp);
91 }
92 int dirfd = open(TEST_FILE_PATH, O_RDONLY | O_DIRECTORY);
93 EXPECT_TRUE(dirfd > 0);
94 ret = fchmodat(dirfd, TEST_FILE_NAME, MODE_0755, 0);
95 EXPECT_EQ(ret, 0);
96
97 chdir(path);
98 close(dirfd);
99 }
100
101 /*
102 * @tc.number : SUB_KERNEL_SYSCALL_FCHMODAT_0200
103 * @tc.name : FchmodatInvalidFdModeFail_0002
104 * @tc.desc : fchmodat invalid file mode bits fail, errno EBADF.
105 * @tc.size : MediumTest
106 * @tc.type : Function
107 * @tc.level : Level 2
108 */
109 HWTEST_F(FchmodatApiTest, FchmodatInvalidFdModeFail_0002, Function | MediumTest | Level2)
110 {
111 int ret = -1;
112 int invalidFd = -1;
113 errno = 0;
114 ret = fchmodat(invalidFd, TEST_FILE_NAME, MODE_0755, 0);
115
116 EXPECT_NE(ret, 0);
117 EXPECT_EQ(errno, EBADF);
118 }
119
120 /*
121 * @tc.number : SUB_KERNEL_SYSCALL_FCHMODAT_0300
122 * @tc.name : FchmodatAT_FDCWDModeSuccess_0003
123 * @tc.desc : fchmodat AT_FDCWD test success.
124 * @tc.size : MediumTest
125 * @tc.type : Function
126 * @tc.level : Level 1
127 */
128 HWTEST_F(FchmodatApiTest, FchmodatAT_FDCWDModeSuccess_0003, Function | MediumTest | Level1)
129 {
130 int ret = -1;
131 int fd = open(TEST_FILE, O_CREAT | O_RDWR, MODE_0644);
132 EXPECT_TRUE(fd > 0);
133 char path[PATH_MAX_LEN];
134 char *dir = getcwd(path, sizeof(path));
135 EXPECT_NE(dir, nullptr);
136 ret = chdir(TEST_FILE_PATH);
137 EXPECT_EQ(ret, 0);
138 ret = fchmodat(AT_FDCWD, TEST_FILE_NAME, MODE_0755, 0);
139 EXPECT_EQ(ret, 0);
140 ret = fstat(fd, &g_statbuf);
141 EXPECT_EQ(ret, 0);
142 EXPECT_EQ((g_statbuf.st_mode & S_IXUSR), S_IXUSR);
143 EXPECT_EQ((g_statbuf.st_mode & S_IXGRP), S_IXGRP);
144 EXPECT_EQ((g_statbuf.st_mode & S_IXOTH), S_IXOTH);
145
146 close(fd);
147 chdir(path);
148 }
149
150 /*
151 * @tc.number : SUB_KERNEL_SYSCALL_FCHMODAT_0400
152 * @tc.name : FchmodatLinkFileModeFail_0004
153 * @tc.desc : fchmodat change link file mode bits when symbol link not follow fail, errno EOPNOTSUPP.
154 * @tc.size : MediumTest
155 * @tc.type : Function
156 * @tc.level : Level 2
157 */
158 HWTEST_F(FchmodatApiTest, FchmodatLinkFileModeFail_0004, Function | MediumTest | Level2)
159 {
160 int ret = -1;
161 int fd = open(TEST_FILE, O_CREAT | O_RDWR, MODE_0644);
162 EXPECT_TRUE(fd > 0);
163 char path[PATH_MAX_LEN];
164 char *dir = getcwd(path, sizeof(path));
165 EXPECT_NE(dir, nullptr);
166 ret = chdir(TEST_FILE_PATH);
167 EXPECT_EQ(ret, 0);
168 ret = symlink(TEST_FILE_NAME, SYMBOL_LINK_NAME);
169 EXPECT_EQ(ret, 0);
170
171 errno = 0;
172 ret = fchmodat(AT_FDCWD, SYMBOL_LINK_NAME, MODE_0600, AT_SYMLINK_NOFOLLOW);
173 EXPECT_NE(ret, 0);
174 EXPECT_EQ(errno, EOPNOTSUPP);
175
176 remove(SYMBOL_LINK_NAME);
177 chdir(path);
178 }
179