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 <csignal>
20 #include <string>
21 #include <vector>
22 #include <fcntl.h>
23 #include <sched.h>
24 #include <unistd.h>
25 #include <bits/syscall.h>
26 #include <gtest/gtest.h>
27 #include <sys/ptrace.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include "securec.h"
31
32 using namespace testing::ext;
33 using namespace std;
34
35 static const int STACK_SIZE = 8 * 1024 * 1024;
36 static const char *TEST_FILE = "/data/local/tmp/exec_test.txt";
37
38 struct CloneFlag {
39 int id;
40 int flag;
41 };
42
43 class ProcessApiTest : public testing::Test {
44 public:
45 static void SetUpTestCase();
46 static void TearDownTestCase();
47 void SetUp();
48 void TearDown();
49 private:
50 };
SetUp()51 void ProcessApiTest::SetUp()
52 {
53 }
TearDown()54 void ProcessApiTest::TearDown()
55 {
56 }
SetUpTestCase()57 void ProcessApiTest::SetUpTestCase()
58 {
59 }
TearDownTestCase()60 void ProcessApiTest::TearDownTestCase()
61 {
62 }
63
CloneTest(void *arg)64 static int CloneTest(void *arg)
65 {
66 return 0;
67 }
68
69 /*
70 * @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0100
71 * @tc.name : CloneSuccess_0001
72 * @tc.desc : success.
73 * @tc.size : MediumTest
74 * @tc.type : Function
75 * @tc.level : Level 1
76 */
HWTEST_F(ProcessApiTest, CloneSuccess_0001, Function | MediumTest | Level1)77 HWTEST_F(ProcessApiTest, CloneSuccess_0001, Function | MediumTest | Level1)
78 {
79 int i;
80 int pid = -1;
81 struct CloneFlag cloneFlag[] = {
82 {1, CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD},
83 {2, CSIGNAL},
84 {3, CLONE_VFORK},
85 {4, CLONE_PARENT},
86 {5, CLONE_NEWNS},
87 {6, CLONE_SETTLS},
88 {7, CLONE_PARENT_SETTID},
89 {8, CLONE_CHILD_CLEARTID},
90 {9, CLONE_CHILD_SETTID},
91 {10, CLONE_NEWUTS},
92 {11, CLONE_NEWIPC},
93 {13, CLONE_NEWPID},
94 {14, CLONE_NEWNET},
95 };
96 char *stack = new char[STACK_SIZE];
97 for (i = 0; i < sizeof(cloneFlag) / sizeof(cloneFlag[0]); i++) {
98 pid = clone(CloneTest, &stack[STACK_SIZE - 1], cloneFlag[i].flag, nullptr);
99 EXPECT_TRUE(pid > 0);
100 waitpid(pid, nullptr, 0);
101 }
102 free(stack);
103 }
104
105 /*
106 * @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0200
107 * @tc.name : CloneInvalidFlagFailed_0002
108 * @tc.desc : clone flag invalid failed errno EINVAL.
109 * @tc.size : MediumTest
110 * @tc.type : Function
111 * @tc.level : Level 2
112 */
HWTEST_F(ProcessApiTest, CloneInvalidFlagFailed_0002, Function | MediumTest | Level2)113 HWTEST_F(ProcessApiTest, CloneInvalidFlagFailed_0002, Function | MediumTest | Level2)
114 {
115 errno = 0;
116 char *stack = new char[STACK_SIZE];
117 pid_t pid = clone(CloneTest, &stack[STACK_SIZE - 1], -1, nullptr);
118 EXPECT_EQ(pid, -1);
119 EXPECT_EQ(errno, EINVAL);
120 }
121
122 /*
123 * @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0300
124 * @tc.name : ExecveCmdSuccess_0003
125 * @tc.desc : execve exec cmd touch success.
126 * @tc.size : MediumTest
127 * @tc.type : Function
128 * @tc.level : Level 1
129 */
HWTEST_F(ProcessApiTest, ExecveCmdSuccess_0003, Function | MediumTest | Level1)130 HWTEST_F(ProcessApiTest, ExecveCmdSuccess_0003, Function | MediumTest | Level1)
131 {
132 int ret;
133 pid_t pid = fork();
134 if (pid == 0) {
135 char cmd[] = "touch";
136 char file[] = "/data/local/tmp/exec_test.txt";
137 char *argv[] = {cmd, file, nullptr};
138 char *envp[] = { nullptr };
139 ret = execve("/bin/touch", argv, envp);
140 EXPECT_EQ(ret, 0);
141 exit(0);
142 }
143 waitpid(pid, nullptr, 0);
144 EXPECT_EQ(access(TEST_FILE, F_OK), 0);
145 remove(TEST_FILE);
146 }
147
148 /*
149 * @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0400
150 * @tc.name : ExecveInvalidParamFailed_0004
151 * @tc.desc : execve exec cmd touch success.
152 * @tc.size : MediumTest
153 * @tc.type : Function
154 * @tc.level : Level 2
155 */
HWTEST_F(ProcessApiTest, ExecveInvalidParamFailed_0004, Function | MediumTest | Level2)156 HWTEST_F(ProcessApiTest, ExecveInvalidParamFailed_0004, Function | MediumTest | Level2)
157 {
158 errno = 0;
159 char cmd[] = "touch";
160 char file[] = "/data/local/tmp/exec_test.txt";
161 char *argv[] = {cmd, file, nullptr};
162 char *envp[] = { nullptr };
163 int ret = execve(nullptr, argv, envp);
164 EXPECT_EQ(ret, -1);
165 EXPECT_EQ(errno, EFAULT);
166 }
167
168 /*
169 * @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0500
170 * @tc.name : ExecveatSuccess_0005
171 * @tc.desc : success.
172 * @tc.size : MediumTest
173 * @tc.type : Function
174 * @tc.level : Level 1
175 */
HWTEST_F(ProcessApiTest, ExecveatSuccess_0005, Function | MediumTest | Level1)176 HWTEST_F(ProcessApiTest, ExecveatSuccess_0005, Function | MediumTest | Level1)
177 {
178 int ret;
179 char cmd[] = "ls";
180 char *argv[] = {cmd, nullptr};
181 char *envp[] = { nullptr };
182 int fd = open("/bin", O_RDONLY | O_DIRECTORY);
183 EXPECT_TRUE(fd > 0);
184
185 pid_t pid = fork();
186 if (pid == 0) {
187 ret = syscall(__NR_execveat, fd, cmd, argv, envp, 0);
188 EXPECT_EQ(ret, 0);
189 exit(0);
190 }
191 waitpid(pid, nullptr, 0);
192 }
193
194 /*
195 * @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0600
196 * @tc.name : ExecveatInvalidFlagsFailed_0006
197 * @tc.desc : execveat invalid flags -1 failed errno EINVAL.
198 * @tc.size : MediumTest
199 * @tc.type : Function
200 * @tc.level : Level 2
201 */
HWTEST_F(ProcessApiTest, ExecveatInvalidFlagsFailed_0006, Function | MediumTest | Level2)202 HWTEST_F(ProcessApiTest, ExecveatInvalidFlagsFailed_0006, Function | MediumTest | Level2)
203 {
204 int ret;
205 char cmd[] = "ls";
206 char *argv[] = {cmd, nullptr};
207 char *envp[] = { nullptr };
208 int fd = open("/bin", O_RDONLY | O_DIRECTORY);
209 EXPECT_TRUE(fd > 0);
210
211 pid_t pid = fork();
212 if (pid == 0) {
213 errno = 0;
214 ret = syscall(__NR_execveat, fd, cmd, argv, envp, -1);
215 EXPECT_EQ(ret, -1);
216 EXPECT_EQ(errno, EINVAL);
217 exit(0);
218 }
219 waitpid(pid, nullptr, 0);
220 }
221
222 /*
223 * @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0700
224 * @tc.name : ExitGroupSyscallSuccess_0007
225 * @tc.desc : __NR_exit_group syscall test success.
226 * @tc.size : MediumTest
227 * @tc.type : Function
228 * @tc.level : Level 1
229 */
HWTEST_F(ProcessApiTest, ExitGroupSyscallSuccess_0007, Function | MediumTest | Level1)230 HWTEST_F(ProcessApiTest, ExitGroupSyscallSuccess_0007, Function | MediumTest | Level1)
231 {
232 int ret;
233 pid_t pid;
234
235 pid = fork();
236 if (pid == 0) {
237 ret = syscall(__NR_exit_group, 0);
238 EXPECT_EQ(ret, 0);
239 exit(0);
240 }
241 waitpid(pid, nullptr, 0);
242 }
243
244 /*
245 * @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0800
246 * @tc.name : GetPidSuccess_0008
247 * @tc.desc : success.
248 * @tc.size : MediumTest
249 * @tc.type : Function
250 * @tc.level : Level 1
251 */
HWTEST_F(ProcessApiTest, GetPidSuccess_0008, Function | MediumTest | Level1)252 HWTEST_F(ProcessApiTest, GetPidSuccess_0008, Function | MediumTest | Level1)
253 {
254 pid_t pid = getpid();
255 EXPECT_TRUE(pid >= 0);
256 }
257
258 /*
259 * @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0900
260 * @tc.name : GetppidGetParentPidSuccess_0009
261 * @tc.desc : getppid get parent pid success.
262 * @tc.size : MediumTest
263 * @tc.type : Function
264 * @tc.level : Level 1
265 */
HWTEST_F(ProcessApiTest, GetppidGetParentPidSuccess_0009, Function | MediumTest | Level1)266 HWTEST_F(ProcessApiTest, GetppidGetParentPidSuccess_0009, Function | MediumTest | Level1)
267 {
268 pid_t ppid = getppid();
269 EXPECT_TRUE(ppid >= 0);
270 }
271
272 /*
273 * @tc.number : SUB_KERNEL_SYSCALL_PROCESS_1000
274 * @tc.name : GetSidSuccess_0010
275 * @tc.desc : success.
276 * @tc.size : MediumTest
277 * @tc.type : Function
278 * @tc.level : Level 1
279 */
HWTEST_F(ProcessApiTest, GetSidSuccess_0010, Function | MediumTest | Level1)280 HWTEST_F(ProcessApiTest, GetSidSuccess_0010, Function | MediumTest | Level1)
281 {
282 pid_t pid = getpid();
283 EXPECT_TRUE(pid >= 0);
284
285 pid_t sid = getsid(pid);
286 EXPECT_TRUE(sid >= 0);
287 }
288
289 /*
290 * @tc.number : SUB_KERNEL_SYSCALL_PROCESS_1100
291 * @tc.name : GetTidSuccess_0011
292 * @tc.desc : success.
293 * @tc.size : MediumTest
294 * @tc.type : Function
295 * @tc.level : Level 1
296 */
HWTEST_F(ProcessApiTest, GetTidSuccess_0011, Function | MediumTest | Level1)297 HWTEST_F(ProcessApiTest, GetTidSuccess_0011, Function | MediumTest | Level1)
298 {
299 pid_t tid = gettid();
300 EXPECT_TRUE(tid >= 0);
301 }
302
303 /*
304 * @tc.number : SUB_KERNEL_SYSCALL_PROCESS_1200
305 * @tc.name : SetTidAddressSuccess_0012
306 * @tc.desc : success.
307 * @tc.size : MediumTest
308 * @tc.type : Function
309 * @tc.level : Level 1
310 */
HWTEST_F(ProcessApiTest, SetTidAddressSuccess_0001, Function | MediumTest | Level1)311 HWTEST_F(ProcessApiTest, SetTidAddressSuccess_0001, Function | MediumTest | Level1)
312 {
313 int newTid = -1;
314 int ret = syscall(__NR_set_tid_address, &newTid);
315 EXPECT_EQ(ret, getpid());
316 }
317
318 /*
319 * @tc.number : SUB_KERNEL_SYSCALL_PROCESS_1300
320 * @tc.name : UnshareFlagsTest_0013
321 * @tc.desc : unshare success.
322 * @tc.size : MediumTest
323 * @tc.type : Function
324 * @tc.level : Level 1
325 */
HWTEST_F(ProcessApiTest, UnshareFlagsTest_0013, Function | MediumTest | Level1)326 HWTEST_F(ProcessApiTest, UnshareFlagsTest_0013, Function | MediumTest | Level1)
327 {
328 int32_t ret = unshare(CLONE_NEWPID);
329 EXPECT_EQ(ret, 0);
330
331 ret = unshare(CLONE_FILES);
332 EXPECT_EQ(ret, 0);
333
334 ret = unshare(CLONE_FS);
335 EXPECT_EQ(ret, 0);
336
337 ret = unshare(CLONE_NEWNS);
338 EXPECT_EQ(ret, 0);
339
340 ret = unshare(CLONE_NEWUTS);
341 EXPECT_EQ(ret, 0);
342
343 ret = unshare(CLONE_NEWIPC);
344 EXPECT_EQ(ret, 0);
345
346 ret = unshare(CLONE_NEWNET);
347 EXPECT_EQ(ret, 0);
348 }
349