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