* Copyright (C) 2024 HiHope Open Source Organization.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <csignal>
#include <string>
#include <vector>
#include <fcntl.h>
#include <sched.h>
#include <unistd.h>
#include <bits/syscall.h>
#include <gtest/gtest.h>
#include <sys/ptrace.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "securec.h"
using namespace testing::ext;
using namespace std;
static const int STACK_SIZE = 8 * 1024 * 1024;
static const char *TEST_FILE = "/data/local/tmp/exec_test.txt";
struct CloneFlag {
int id;
int flag;
};
class ProcessApiTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp();
void TearDown();
private:
};
void ProcessApiTest::SetUp()
{
}
void ProcessApiTest::TearDown()
{
}
void ProcessApiTest::SetUpTestCase()
{
}
void ProcessApiTest::TearDownTestCase()
{
}
static int CloneTest(void *arg)
{
return 0;
}
* @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0100
* @tc.name : CloneSuccess_0001
* @tc.desc : success.
* @tc.size : MediumTest
* @tc.type : Function
* @tc.level : Level 1
*/
HWTEST_F(ProcessApiTest, CloneSuccess_0001, Function | MediumTest | Level1)
{
int i;
int pid = -1;
struct CloneFlag cloneFlag[] = {
{1, CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD},
{2, CSIGNAL},
{3, CLONE_VFORK},
{4, CLONE_PARENT},
{5, CLONE_NEWNS},
{6, CLONE_SETTLS},
{7, CLONE_PARENT_SETTID},
{8, CLONE_CHILD_CLEARTID},
{9, CLONE_CHILD_SETTID},
{10, CLONE_NEWUTS},
{11, CLONE_NEWIPC},
{13, CLONE_NEWPID},
{14, CLONE_NEWNET},
};
char *stack = new char[STACK_SIZE];
for (i = 0; i < sizeof(cloneFlag) / sizeof(cloneFlag[0]); i++) {
pid = clone(CloneTest, &stack[STACK_SIZE - 1], cloneFlag[i].flag, nullptr);
EXPECT_TRUE(pid > 0);
waitpid(pid, nullptr, 0);
}
free(stack);
}
* @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0200
* @tc.name : CloneInvalidFlagFailed_0002
* @tc.desc : clone flag invalid failed errno EINVAL.
* @tc.size : MediumTest
* @tc.type : Function
* @tc.level : Level 2
*/
HWTEST_F(ProcessApiTest, CloneInvalidFlagFailed_0002, Function | MediumTest | Level2)
{
errno = 0;
char *stack = new char[STACK_SIZE];
pid_t pid = clone(CloneTest, &stack[STACK_SIZE - 1], -1, nullptr);
EXPECT_EQ(pid, -1);
EXPECT_EQ(errno, EINVAL);
}
* @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0300
* @tc.name : ExecveCmdSuccess_0003
* @tc.desc : execve exec cmd touch success.
* @tc.size : MediumTest
* @tc.type : Function
* @tc.level : Level 1
*/
HWTEST_F(ProcessApiTest, ExecveCmdSuccess_0003, Function | MediumTest | Level1)
{
int ret;
pid_t pid = fork();
if (pid == 0) {
char cmd[] = "touch";
char file[] = "/data/local/tmp/exec_test.txt";
char *argv[] = {cmd, file, nullptr};
char *envp[] = { nullptr };
ret = execve("/bin/touch", argv, envp);
EXPECT_EQ(ret, 0);
exit(0);
}
waitpid(pid, nullptr, 0);
EXPECT_EQ(access(TEST_FILE, F_OK), 0);
remove(TEST_FILE);
}
* @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0400
* @tc.name : ExecveInvalidParamFailed_0004
* @tc.desc : execve exec cmd touch success.
* @tc.size : MediumTest
* @tc.type : Function
* @tc.level : Level 2
*/
HWTEST_F(ProcessApiTest, ExecveInvalidParamFailed_0004, Function | MediumTest | Level2)
{
errno = 0;
char cmd[] = "touch";
char file[] = "/data/local/tmp/exec_test.txt";
char *argv[] = {cmd, file, nullptr};
char *envp[] = { nullptr };
int ret = execve(nullptr, argv, envp);
EXPECT_EQ(ret, -1);
EXPECT_EQ(errno, EFAULT);
}
* @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0500
* @tc.name : ExecveatSuccess_0005
* @tc.desc : success.
* @tc.size : MediumTest
* @tc.type : Function
* @tc.level : Level 1
*/
HWTEST_F(ProcessApiTest, ExecveatSuccess_0005, Function | MediumTest | Level1)
{
int ret;
char cmd[] = "ls";
char *argv[] = {cmd, nullptr};
char *envp[] = { nullptr };
int fd = open("/bin", O_RDONLY | O_DIRECTORY);
EXPECT_TRUE(fd > 0);
pid_t pid = fork();
if (pid == 0) {
ret = syscall(__NR_execveat, fd, cmd, argv, envp, 0);
EXPECT_EQ(ret, 0);
exit(0);
}
waitpid(pid, nullptr, 0);
}
* @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0600
* @tc.name : ExecveatInvalidFlagsFailed_0006
* @tc.desc : execveat invalid flags -1 failed errno EINVAL.
* @tc.size : MediumTest
* @tc.type : Function
* @tc.level : Level 2
*/
HWTEST_F(ProcessApiTest, ExecveatInvalidFlagsFailed_0006, Function | MediumTest | Level2)
{
int ret;
char cmd[] = "ls";
char *argv[] = {cmd, nullptr};
char *envp[] = { nullptr };
int fd = open("/bin", O_RDONLY | O_DIRECTORY);
EXPECT_TRUE(fd > 0);
pid_t pid = fork();
if (pid == 0) {
errno = 0;
ret = syscall(__NR_execveat, fd, cmd, argv, envp, -1);
EXPECT_EQ(ret, -1);
EXPECT_EQ(errno, EINVAL);
exit(0);
}
waitpid(pid, nullptr, 0);
}
* @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0700
* @tc.name : ExitGroupSyscallSuccess_0007
* @tc.desc : __NR_exit_group syscall test success.
* @tc.size : MediumTest
* @tc.type : Function
* @tc.level : Level 1
*/
HWTEST_F(ProcessApiTest, ExitGroupSyscallSuccess_0007, Function | MediumTest | Level1)
{
int ret;
pid_t pid;
pid = fork();
if (pid == 0) {
ret = syscall(__NR_exit_group, 0);
EXPECT_EQ(ret, 0);
exit(0);
}
waitpid(pid, nullptr, 0);
}
* @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0800
* @tc.name : GetPidSuccess_0008
* @tc.desc : success.
* @tc.size : MediumTest
* @tc.type : Function
* @tc.level : Level 1
*/
HWTEST_F(ProcessApiTest, GetPidSuccess_0008, Function | MediumTest | Level1)
{
pid_t pid = getpid();
EXPECT_TRUE(pid >= 0);
}
* @tc.number : SUB_KERNEL_SYSCALL_PROCESS_0900
* @tc.name : GetppidGetParentPidSuccess_0009
* @tc.desc : getppid get parent pid success.
* @tc.size : MediumTest
* @tc.type : Function
* @tc.level : Level 1
*/
HWTEST_F(ProcessApiTest, GetppidGetParentPidSuccess_0009, Function | MediumTest | Level1)
{
pid_t ppid = getppid();
EXPECT_TRUE(ppid >= 0);
}
* @tc.number : SUB_KERNEL_SYSCALL_PROCESS_1000
* @tc.name : GetSidSuccess_0010
* @tc.desc : success.
* @tc.size : MediumTest
* @tc.type : Function
* @tc.level : Level 1
*/
HWTEST_F(ProcessApiTest, GetSidSuccess_0010, Function | MediumTest | Level1)
{
pid_t pid = getpid();
EXPECT_TRUE(pid >= 0);
pid_t sid = getsid(pid);
EXPECT_TRUE(sid >= 0);
}
* @tc.number : SUB_KERNEL_SYSCALL_PROCESS_1100
* @tc.name : GetTidSuccess_0011
* @tc.desc : success.
* @tc.size : MediumTest
* @tc.type : Function
* @tc.level : Level 1
*/
HWTEST_F(ProcessApiTest, GetTidSuccess_0011, Function | MediumTest | Level1)
{
pid_t tid = gettid();
EXPECT_TRUE(tid >= 0);
}
* @tc.number : SUB_KERNEL_SYSCALL_PROCESS_1200
* @tc.name : SetTidAddressSuccess_0012
* @tc.desc : success.
* @tc.size : MediumTest
* @tc.type : Function
* @tc.level : Level 1
*/
HWTEST_F(ProcessApiTest, SetTidAddressSuccess_0001, Function | MediumTest | Level1)
{
int newTid = -1;
int ret = syscall(__NR_set_tid_address, &newTid);
EXPECT_EQ(ret, getpid());
}
* @tc.number : SUB_KERNEL_SYSCALL_PROCESS_1300
* @tc.name : UnshareFlagsTest_0013
* @tc.desc : unshare success.
* @tc.size : MediumTest
* @tc.type : Function
* @tc.level : Level 1
*/
HWTEST_F(ProcessApiTest, UnshareFlagsTest_0013, Function | MediumTest | Level1)
{
int32_t ret = unshare(CLONE_NEWPID);
EXPECT_EQ(ret, 0);
ret = unshare(CLONE_FILES);
EXPECT_EQ(ret, 0);
ret = unshare(CLONE_FS);
EXPECT_EQ(ret, 0);
ret = unshare(CLONE_NEWNS);
EXPECT_EQ(ret, 0);
ret = unshare(CLONE_NEWUTS);
EXPECT_EQ(ret, 0);
ret = unshare(CLONE_NEWIPC);
EXPECT_EQ(ret, 0);
ret = unshare(CLONE_NEWNET);
EXPECT_EQ(ret, 0);
}