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