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 <malloc.h>
24 #include <unistd.h>
25 #include <arpa/inet.h>
26 #include <gtest/gtest.h>
27 #include <netinet/in.h>
28 #include <sys/mman.h>
29 #include <sys/stat.h>
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include "securec.h"
33
34 using namespace testing::ext;
35
36 class HatsMprotectTest : public testing::Test {
37 public:
38 static void SetUpTestCase();
39 static void TearDownTestCase();
40 void SetUp();
41 void TearDown();
42 private:
43 };
SetUp()44 void HatsMprotectTest::SetUp()
45 {
46 }
47
TearDown()48 void HatsMprotectTest::TearDown()
49 {
50 }
51
SetUpTestCase()52 void HatsMprotectTest::SetUpTestCase()
53 {
54 }
55
TearDownTestCase()56 void HatsMprotectTest::TearDownTestCase()
57 {
58 }
59
60 /*
61 * @tc.number : SUB_KERNEL_SYSCALL_MPROTECT_0100
62 * @tc.name : MprotectWriteSuccess_0001
63 * @tc.desc : mprotect changes the access protections to PROT_WRITE successfully.
64 * @tc.size : MediumTest
65 * @tc.type : Function
66 * @tc.level : Level 1
67 */
HWTEST_F(HatsMprotectTest, MprotectWriteSuccess_0001, Function | MediumTest | Level1)68 HWTEST_F(HatsMprotectTest, MprotectWriteSuccess_0001, Function | MediumTest | Level1)
69 {
70 int ret;
71 int pagesize;
72 struct sigaction sa;
73
74 sa.sa_flags = SA_SIGINFO;
75 sigemptyset(&sa.sa_mask);
76 EXPECT_NE(sigaction(SIGSEGV, &sa, nullptr), -1);
77
78 pagesize = sysconf(_SC_PAGE_SIZE);
79 EXPECT_NE(pagesize, -1);
80
81 // Allocate a buffer aligned on a page boundary; initial protection is PROT_WRITE.
82 void *buffer = memalign(pagesize, 4 * pagesize);
83 EXPECT_NE(buffer, nullptr);
84
85 ret = mprotect(buffer, pagesize, PROT_WRITE);
86 EXPECT_EQ(ret, 0);
87 }
88
89 /*
90 * @tc.number : SUB_KERNEL_SYSCALL_MPROTECT_0200
91 * @tc.name : MprotectExeSuccess_0002
92 * @tc.desc : mprotect changes the access protections to PROT_EXEC successfully.
93 * @tc.size : MediumTest
94 * @tc.type : Function
95 * @tc.level : Level 1
96 */
HWTEST_F(HatsMprotectTest, MprotectExeSuccess_0002, Function | MediumTest | Level1)97 HWTEST_F(HatsMprotectTest, MprotectExeSuccess_0002, Function | MediumTest | Level1)
98 {
99 int ret;
100 int pagesize;
101 struct sigaction sa;
102
103 sa.sa_flags = SA_SIGINFO;
104 sigemptyset(&sa.sa_mask);
105 EXPECT_NE(sigaction(SIGSEGV, &sa, nullptr), -1);
106
107 pagesize = sysconf(_SC_PAGE_SIZE);
108 EXPECT_NE(pagesize, -1);
109
110 // Allocate a buffer aligned on a page boundary; initial protection is PROT_EXEC.
111 void *buf = memalign(pagesize, 4 * pagesize);
112 EXPECT_NE(buf, nullptr);
113
114 ret = mprotect(buf, pagesize, PROT_EXEC);
115 EXPECT_EQ(ret, 0);
116 }
117
118 /*
119 * @tc.number : SUB_KERNEL_SYSCALL_MPROTECT_0300
120 * @tc.name : MprotectAddrInvalid_0003
121 * @tc.desc : mprotect changes the access protections to PROT_READ failed for invalid address,error code is ENOMEM.
122 * @tc.size : MediumTest
123 * @tc.type : Function
124 * @tc.level : Level 2
125 */
HWTEST_F(HatsMprotectTest, MprotectAddrInvalid_0003, Function | MediumTest | Level2)126 HWTEST_F(HatsMprotectTest, MprotectAddrInvalid_0003, Function | MediumTest | Level2)
127 {
128 int ret;
129 int pagesize;
130 struct sigaction sa;
131
132 sa.sa_flags = SA_SIGINFO;
133 sigemptyset(&sa.sa_mask);
134 EXPECT_NE(sigaction(SIGSEGV, &sa, nullptr), -1);
135
136 pagesize = sysconf(_SC_PAGE_SIZE);
137 EXPECT_NE(pagesize, -1);
138
139 void *buf = nullptr;
140 errno = 0;
141 ret = mprotect(buf, pagesize, PROT_READ);
142 EXPECT_EQ(ret, -1);
143 EXPECT_EQ(errno, ENOMEM);
144 }
145
146 /*
147 * @tc.number : SUB_KERNEL_SYSCALL_MPROTECT_0400
148 * @tc.name : MprotectFlagInvalid_0004
149 * @tc.desc : mprotect changes the access protections to PROT_READ failed for flag invalid, error code is EINVAL.
150 * @tc.size : MediumTest
151 * @tc.type : Function
152 * @tc.level : Level 2
153 */
HWTEST_F(HatsMprotectTest, MprotectFlagInvalid_0004, Function | MediumTest | Level2)154 HWTEST_F(HatsMprotectTest, MprotectFlagInvalid_0004, Function | MediumTest | Level2)
155 {
156 int ret;
157 int pagesize;
158 struct sigaction sa;
159
160 sa.sa_flags = SA_SIGINFO;
161 sigemptyset(&sa.sa_mask);
162 EXPECT_NE(sigaction(SIGSEGV, &sa, nullptr), -1);
163
164 pagesize = sysconf(_SC_PAGE_SIZE);
165 EXPECT_NE(pagesize, -1);
166
167 // Allocate a buffer aligned on a page boundary; initial protection is invalid value of 0xFF.
168 void *buf = memalign(pagesize, 4 * pagesize);
169 EXPECT_NE(buf, nullptr);
170
171 errno = 0;
172 ret = mprotect(buf, pagesize, 0xFF);
173
174 EXPECT_EQ(ret, -1);
175 EXPECT_EQ(errno, EINVAL);
176 }
177
178 /*
179 * @tc.number : SUB_KERNEL_SYSCALL_MPROTECT_0500
180 * @tc.name : MprotectUpDownInvalid_0005
181 * @tc.desc : When PROT_GROWSUP and PROT_GROWSDOWN specified change access protections failed,
182 * @tc.size : MediumTest
183 * @tc.type : Function
184 * @tc.level : Level 2
185 */
HWTEST_F(HatsMprotectTest, MprotectUpDownInvalid_0005, Function | MediumTest | Level2)186 HWTEST_F(HatsMprotectTest, MprotectUpDownInvalid_0005, Function | MediumTest | Level2)
187 {
188 int ret;
189 int pagesize;
190 struct sigaction sa;
191
192 sa.sa_flags = SA_SIGINFO;
193 sigemptyset(&sa.sa_mask);
194 EXPECT_NE(sigaction(SIGSEGV, &sa, nullptr), -1);
195
196 pagesize = sysconf(_SC_PAGE_SIZE);
197 EXPECT_NE(pagesize, -1);
198
199 // Allocate a buffer aligned on a page boundary; initial protection are PROT_GROWSUP and PROT_GROWSDOWN.
200 void *buf = memalign(pagesize, 4 * pagesize);
201 EXPECT_NE(buf, nullptr);
202
203 errno = 0;
204 ret = mprotect(buf, pagesize, PROT_GROWSUP | PROT_GROWSDOWN);
205
206 EXPECT_EQ(ret, -1);
207 EXPECT_EQ(errno, EINVAL);
208 }
209
210 /*
211 * @tc.number : SUB_KERNEL_SYSCALL_MPROTECT_0600
212 * @tc.name : MprotectPROT_NONETestSuccess_0006
213 * @tc.desc : mprotect PROT_NONE flag test successfully.
214 * @tc.size : MediumTest
215 * @tc.type : Function
216 * @tc.level : Level 1
217 */
HWTEST_F(HatsMprotectTest, MprotectPROT_NONETestSuccess_0006, Function | MediumTest | Level1)218 HWTEST_F(HatsMprotectTest, MprotectPROT_NONETestSuccess_0006, Function | MediumTest | Level1)
219 {
220 int ret;
221 int pagesize;
222 struct sigaction sa;
223
224 sa.sa_flags = SA_SIGINFO;
225 sigemptyset(&sa.sa_mask);
226 EXPECT_NE(sigaction(SIGSEGV, &sa, nullptr), -1);
227
228 pagesize = sysconf(_SC_PAGE_SIZE);
229 EXPECT_NE(pagesize, -1);
230
231 void *buffer = memalign(pagesize, 4 * pagesize);
232 EXPECT_NE(buffer, nullptr);
233
234 ret = mprotect(buffer, pagesize, PROT_NONE);
235 EXPECT_EQ(ret, 0);
236 }
237