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 29using namespace testing::ext; 30using namespace std; 31 32static const int PATH_MAX_LEN = 128; 33static const char *TEST_FILE = "/data/local/tmp/fchownat.txt"; 34static const char *TEST_FILE_PATH = "/data/local/tmp"; 35static const char *TEST_FILE_NAME = "fchownat.txt"; 36static const char *SYMBOL_LINK_NAME = "TestFchmodatSymlink"; 37mode_t MODE_0644 = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 38mode_t MODE_0755 = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; 39 40class FchownatApiTest : public testing::Test { 41public: 42 static void SetUpTestCase(); 43 static void TearDownTestCase(); 44 void SetUp(); 45 void TearDown(); 46private: 47}; 48void FchownatApiTest::SetUp() 49{ 50} 51void FchownatApiTest::TearDown() 52{ 53} 54void FchownatApiTest::SetUpTestCase() 55{ 56} 57void 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 */ 69HWTEST_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 */ 104HWTEST_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 */ 144HWTEST_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 */ 161HWTEST_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 */ 204HWTEST_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 */ 247HWTEST_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