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 #include <climits>
16 #include <sys/prctl.h>
17 #include <gtest/gtest.h>
18 #include <linux/capability.h>
19 #include <sys/capability.h>
20 #include <sys/mman.h>
21 #include "securec.h"
22 
23 using namespace testing::ext;
24 using namespace std;
25 
26 static const int BUFFER_SIZE = 1024;
27 static const int NUMBER_PAGE = 3;
28 
29 class HatsPrctlSyscallTest : public testing::Test {
30 public:
31     static void SetUpTestCase();
32     static void TearDownTestCase();
33     void SetUp();
34     void TearDown();
35 private:
36 };
SetUp()37 void HatsPrctlSyscallTest::SetUp()
38 {
39 }
TearDown()40 void HatsPrctlSyscallTest::TearDown()
41 {
42 }
SetUpTestCase()43 void HatsPrctlSyscallTest::SetUpTestCase()
44 {
45 }
TearDownTestCase()46 void HatsPrctlSyscallTest::TearDownTestCase()
47 {
48 }
49 
50 /*
51  * @tc.number : SUB_KERNEL_SYSCALL_PRCTL_0100
52  * @tc.name   : PrctlOptionTestSuccess_0001
53  * @tc.desc   : prctl option PR_SET_NAME/PR_GET_NAME/PR_SET_PDEATHSIG/PR_GET_PDEATHSIG test success.
54  * @tc.size   : MediumTest
55  * @tc.type   : Function
56  * @tc.level  : Level 1
57  */
HWTEST_F(HatsPrctlSyscallTest, PrctlOptionTestSuccess_0001, Function | MediumTest | Level1)58 HWTEST_F(HatsPrctlSyscallTest, PrctlOptionTestSuccess_0001, Function | MediumTest | Level1)
59 {
60     unsigned long setOption[2];
61     unsigned long getOption[2];
62     char name[] = "thread_name";
63     char buffer[BUFFER_SIZE] = { 0 };
64 
65     // prctl set and get PR_SET_NAME test success
66     int ret = prctl(PR_SET_NAME, name);
67     EXPECT_EQ(ret, 0);
68 
69     ret = prctl(PR_GET_NAME, buffer);
70     EXPECT_EQ(ret, 0);
71     EXPECT_STREQ(buffer, name);
72 
73     // prctl set and get PR_SET_PDEATHSIG success
74     setOption[0] = SIGUSR2;
75     ret = prctl(PR_SET_PDEATHSIG, setOption[0]);
76     EXPECT_EQ(ret, 0);
77 
78     getOption[0] = 0;
79     ret = prctl(PR_GET_PDEATHSIG, &getOption[0]);
80     EXPECT_EQ(ret, 0);
81     EXPECT_EQ(getOption[0], setOption[0]);
82 }
83 
84 /*
85  * @tc.number : SUB_KERNEL_SYSCALL_PRCTL_0200
86  * @tc.name   : PrctlOptionTestSuccess_0002
87  * @tc.desc   : prctl option PR_SET_KEEPCAPS/PR_CAPBSET_READ/PR_CAPBSET_DROP/PR_CAP_AMBIENT test success.
88  * @tc.size   : MediumTest
89  * @tc.type   : Function
90  * @tc.level  : Level 1
91  */
HWTEST_F(HatsPrctlSyscallTest, PrctlOptionTestSuccess_0002, Function | MediumTest | Level1)92 HWTEST_F(HatsPrctlSyscallTest, PrctlOptionTestSuccess_0002, Function | MediumTest | Level1)
93 {
94     unsigned long setOption[2];
95     unsigned long getOption[2];
96 
97     // prctl PR_SET_KEEPCAPS and PR_GET_KEEPCAPS success
98     setOption[0] = 1;
99     int ret = prctl(PR_SET_KEEPCAPS, setOption[0]);
100     EXPECT_EQ(ret, 0);
101 
102     ret = prctl(PR_GET_KEEPCAPS, &getOption[0]);
103     EXPECT_GE(ret, 0);
104 
105     // prctl PR_CAPBSET_READ success
106     setOption[0] = 1;
107     ret = prctl(PR_CAPBSET_READ, setOption[0]);
108     EXPECT_GE(ret, 0);
109 
110     // prctl PR_CAPBSET_DROP success
111     setOption[0] = 0;
112     setOption[0] = 0;
113     ret = prctl(PR_CAPBSET_DROP, setOption[0], setOption[1], 0, 0);
114     EXPECT_EQ(ret, 0);
115 
116     // prctl PR_CAP_AMBIENT success
117     setOption[0] = 1;
118     setOption[0] = ULONG_MAX;
119     ret = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, 0, 0, 0);
120     EXPECT_EQ(ret, 0);
121 
122     size_t pageSize = static_cast<size_t>(sysconf(_SC_PAGESIZE));
123     void *addr = nullptr;
124     addr = mmap(NULL, pageSize * NUMBER_PAGE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
125     ret = prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, addr, pageSize * NUMBER_PAGE, "anonymous map space");
126     EXPECT_EQ(ret, 0);
127     munmap(addr, pageSize * NUMBER_PAGE);
128 }
129 
130 /*
131  * @tc.number : SUB_KERNEL_SYSCALL_PRCTL_0300
132  * @tc.name   : PrctlOptionTestSuccess_0003
133  * @tc.desc   : prctl option PR_GET_SECUREBITS/PR_GET_GECUREBITS/PR_SET_DUMPABLE/PR_GET_DUMPABLE test success.
134  * @tc.size   : MediumTest
135  * @tc.type   : Function
136  * @tc.level  : Level 1
137  */
HWTEST_F(HatsPrctlSyscallTest, PrctlOptionTestSuccess_0003, Function | MediumTest | Level1)138 HWTEST_F(HatsPrctlSyscallTest, PrctlOptionTestSuccess_0003, Function | MediumTest | Level1)
139 {
140     unsigned long setOption[2];
141     unsigned long getOption[2];
142 
143     // prctl PR_GET_SECUREBITS and PR_GET_GECUREBITS success
144     int ret = prctl(PR_SET_SECUREBITS, PR_SET_SECUREBITS, 0, 0, 0);
145     EXPECT_EQ(ret, 0);
146 
147     getOption[0] = 0;
148     ret = prctl(PR_GET_SECUREBITS, &getOption[0]);
149     EXPECT_GE(ret, 0);
150 
151     // prctl PR_SET_DUMPABLE and PR_GET_DUMPABLE success
152     setOption[0] = 1;
153     setOption[1] = 0;
154     ret = prctl(PR_SET_DUMPABLE, setOption[0], setOption[1], 0, 0);
155     EXPECT_EQ(ret, 0);
156 
157     ret = prctl(PR_GET_DUMPABLE, &getOption[0]);
158     EXPECT_GE(ret, 0);
159 }
160 
161 /*
162  * @tc.number : SUB_KERNEL_SYSCALL_PRCTL_0400
163  * @tc.name   : PrctlOptionTestSuccess_0004
164  * @tc.desc   : prctl option PR_SET_CHILD_SUBREAPER/PR_GET_CHILD_SUBREAPER test success.
165  * @tc.size   : MediumTest
166  * @tc.type   : Function
167  * @tc.level  : Level 1
168  */
HWTEST_F(HatsPrctlSyscallTest, PrctlOptionTestSuccess_0004, Function | MediumTest | Level1)169 HWTEST_F(HatsPrctlSyscallTest, PrctlOptionTestSuccess_0004, Function | MediumTest | Level1)
170 {
171     unsigned long setOption[2];
172     unsigned long getOption[2];
173 
174     // prctl PR_SET_CHILD_SUBREAPER and PR_GET_CHILD_SUBREAPER success
175     setOption[0] = 1;
176     int ret = prctl(PR_SET_CHILD_SUBREAPER, setOption[0]);
177     EXPECT_EQ(ret, 0);
178 
179     getOption[0] = 0;
180     ret = prctl(PR_GET_CHILD_SUBREAPER, &getOption[0]);
181     EXPECT_EQ(ret, 0);
182     EXPECT_EQ(getOption[0], setOption[0]);
183 }
184 
185 /*
186  * @tc.number : SUB_KERNEL_SYSCALL_PRCTL_0500
187  * @tc.name   : PrctlOptionTestSuccess_0005
188  * @tc.desc   : prctl option PR_SET_NO_NEW_PRIVS/PR_GET_NO_NEW_PRIVS test success.
189  * @tc.size   : MediumTest
190  * @tc.type   : Function
191  * @tc.level  : Level 1
192  */
HWTEST_F(HatsPrctlSyscallTest, PrctlOptionTestSuccess_0005, Function | MediumTest | Level1)193 HWTEST_F(HatsPrctlSyscallTest, PrctlOptionTestSuccess_0005, Function | MediumTest | Level1)
194 {
195     // prctl PR_SET_NO_NEW_PRIVS and PR_GET_NO_NEW_PRIVS success
196     int ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
197     EXPECT_EQ(ret, 0);
198 
199     ret = prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0);
200     EXPECT_GE(ret, 0);
201 }
202