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