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