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 <unistd.h>
24 #include <malloc.h>
25 #include <arpa/inet.h>
26 #include <gtest/gtest.h>
27 #include <netinet/in.h>
28 #include <sys/stat.h>
29 #include <sys/mman.h>
30 #include <sys/socket.h>
31 #include <sys/types.h>
32 #include "securec.h"
33
34 using namespace testing::ext;
35
36 static const int SIZE_1M = 1024 * 1024;
37 static const int SIZE_1G = 1024 * 1024 * 1024;
38 static const char *TEST_FILE = "/data/local/tmp/mmap_test";
39
40 class HatsMmapSyscallTest : public testing::Test {
41 public:
42 static void SetUpTestCase();
43 static void TearDownTestCase();
44 void SetUp();
45 void TearDown();
46 private:
47 };
SetUp()48 void HatsMmapSyscallTest::SetUp()
49 {
50 }
51
TearDown()52 void HatsMmapSyscallTest::TearDown()
53 {
54 }
55
SetUpTestCase()56 void HatsMmapSyscallTest::SetUpTestCase()
57 {
58 }
59
TearDownTestCase()60 void HatsMmapSyscallTest::TearDownTestCase()
61 {
62 unlink(TEST_FILE);
63 }
64
65 /*
66 * @tc.number : SUB_KERNEL_SYSCALL_MMAPSYSCALL_0100
67 * @tc.name : MmapSyscallPortTestSuccess_0001
68 * @tc.desc : Mmap sets prot PROT_READ/PROT_WRITE/PROT_EXEC/PROT_NONE test successfully.
69 * @tc.size : MediumTest
70 * @tc.type : Function
71 * @tc.level : Level 1
72 */
73 HWTEST_F(HatsMmapSyscallTest, MmapSyscallPortTestSuccess_0001, Function | MediumTest | Level1)
74 {
75 size_t size = SIZE_1M;
76 void *va = mmap(nullptr, size, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
77 EXPECT_NE(va, MAP_FAILED);
78
79 int ret = munmap(va, size);
80 EXPECT_EQ(ret, 0);
81
82 va = mmap(nullptr, size, PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
83 EXPECT_NE(va, MAP_FAILED);
84
85 ret = munmap(va, size);
86 EXPECT_EQ(ret, 0);
87
88 va = mmap(nullptr, size, PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
89 EXPECT_NE(va, MAP_FAILED);
90
91 ret = munmap(va, size);
92 EXPECT_EQ(ret, 0);
93
94 va = mmap(nullptr, size, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
95 EXPECT_NE(va, MAP_FAILED);
96
97 ret = munmap(va, size);
98 EXPECT_EQ(ret, 0);
99 }
100
101 /*
102 * @tc.number : SUB_KERNEL_SYSCALL_MMAPSYSCALL_0200
103 * @tc.name : MmapFlagTestSuccess_0002
104 * @tc.desc : Mmap sets flag MAP_SHARED/MAP_PRIVATE/MAP_FIXED/MAP_ANONYMOUS test successfully.
105 * @tc.size : MediumTest
106 * @tc.type : Function
107 * @tc.level : Level 1
108 */
109 HWTEST_F(HatsMmapSyscallTest, MmapFlagTestSuccess_0002, Function | MediumTest | Level1)
110 {
111 size_t size = SIZE_1M;
112 int fd = open(TEST_FILE, O_CREAT | O_RDWR, 0664);
113
114 // flag MAP_SHARED and MAP_PRIVATE test
115 void *va = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, fd, 0);
116 EXPECT_NE(va, MAP_FAILED);
117
118 int ret = munmap(va, size);
119 EXPECT_EQ(ret, 0);
120 close(fd);
121
122 // flag MAP_FIXED and MAP_ANONYMOUS test
123 void *addr = reinterpret_cast<void *>(0x200000);
124 va = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
125 EXPECT_NE(va, MAP_FAILED);
126
127 ret = munmap(va, size);
128 EXPECT_EQ(ret, 0);
129 }
130
131 /*
132 * @tc.number : SUB_KERNEL_SYSCALL_MMAPSYSCALL_0300
133 * @tc.name : MmapFlagTestSuccess_0003
134 * @tc.desc : Mmap sets flag MAP_LOCKED/MAP_NORESERVE/MAP_POPULATE/MAP_STACK test successfully.
135 * @tc.size : MediumTest
136 * @tc.type : Function
137 * @tc.level : Level 1
138 */
139 HWTEST_F(HatsMmapSyscallTest, MmapFlagTestSuccess_0003, Function | MediumTest | Level1)
140 {
141 size_t size = SIZE_1M;
142
143 // flag MAP_LOCKED test
144 void *va = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_LOCKED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
145 EXPECT_NE(va, MAP_FAILED);
146
147 int ret = munmap(va, size);
148 EXPECT_EQ(ret, 0);
149
150 // flag MAP_NORESERVE test
151 va = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_NORESERVE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
152 EXPECT_NE(va, MAP_FAILED);
153
154 ret = munmap(va, size);
155 EXPECT_EQ(ret, 0);
156
157 // flag MAP_POPULATE test
158 va = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
159 EXPECT_NE(va, MAP_FAILED);
160
161 ret = munmap(va, size);
162 EXPECT_EQ(ret, 0);
163
164 // flag MAP_STACK test
165 va = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_STACK | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
166 EXPECT_NE(va, MAP_FAILED);
167
168 ret = munmap(va, size);
169 EXPECT_EQ(ret, 0);
170 }
171
172 /*
173 * @tc.number : SUB_KERNEL_SYSCALL_MMAPSYSCALL_0400
174 * @tc.name : MmapFlagTestSuccess_0004
175 * @tc.desc : Mmap sets flag MAP_FILE/MAP_HUGE_2MB/MAP_HUGE_1GB successfully.
176 * @tc.size : MediumTest
177 * @tc.type : Function
178 * @tc.level : Level 1
179 */
180 HWTEST_F(HatsMmapSyscallTest, MmapFlagTestSuccess_0004, Function | MediumTest | Level1)
181 {
182 size_t size = SIZE_1M;
183 int fd = open(TEST_FILE, O_CREAT | O_RDWR, 0664);
184 ASSERT_TRUE(fd > 0);
185
186 // flag MAP_FILE test
187 void *va = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0);
188 EXPECT_NE(va, MAP_FAILED);
189
190 int ret = munmap(va, size);
191 EXPECT_EQ(ret, 0);
192 close(fd);
193
194 // flag MAP_HUGE_2MB test
195 size = SIZE_1M * 2;
196 va = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_HUGE_2MB | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
197 EXPECT_NE(va, MAP_FAILED);
198
199 ret = munmap(va, size);
200 EXPECT_EQ(ret, 0);
201
202 // flag MAP_HUGE_1GB test
203 size = SIZE_1G;
204 va = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_HUGE_1GB | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
205 EXPECT_NE(va, MAP_FAILED);
206
207 ret = munmap(va, size);
208 EXPECT_EQ(ret, 0);
209 }
210
211 /*
212 * @tc.number : SUB_KERNEL_SYSCALL_MMAPSYSCALL_0500
213 * @tc.name : MmapAndMunmapInvalidSizeFailed_0005
214 * @tc.desc : Mmap map addr failed for size 0.
215 * @tc.size : MediumTest
216 * @tc.type : Function
217 * @tc.level : Level 2
218 */
219 HWTEST_F(HatsMmapSyscallTest, MmapAndMunmapInvalidSizeFailed_0005, Function | MediumTest | Level2)
220 {
221 size_t size = 0;
222 errno = 0;
223 void *va = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
224 EXPECT_EQ(va, MAP_FAILED);
225 EXPECT_EQ(errno, EINVAL);
226
227 errno = 0;
228 int ret = munmap(va, size);
229 EXPECT_EQ(ret, -1);
230 EXPECT_EQ(errno, EINVAL);
231 }
232
233 /*
234 * @tc.number : SUB_KERNEL_SYSCALL_MMAPSYSCALL_0600
235 * @tc.name : MremapSyscallToLargeSuccess_0006
236 * @tc.desc : Mremap maps with flag 0 from small memory to large successfully.
237 * @tc.size : MediumTest
238 * @tc.type : Function
239 * @tc.level : Level 2
240 */
241 HWTEST_F(HatsMmapSyscallTest, MremapSyscallToLargeSuccess_0006, Function | MediumTest | Level2)
242 {
243 size_t size = SIZE_1M;
244 size_t newSize = 2048;
245 void *va = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
246 EXPECT_NE(va, MAP_FAILED);
247
248 void* vaNew = mremap(va, size, newSize, 0);
249 EXPECT_NE(vaNew, MAP_FAILED);
250
251 int ret = munmap(va, size);
252 EXPECT_EQ(ret, 0);
253
254 ret = munmap(vaNew, newSize);
255 EXPECT_EQ(ret, 0);
256 }
257
258 /*
259 * @tc.number : SUB_KERNEL_SYSCALL_MMAPSYSCALL_0700
260 * @tc.name : MremapSyscallToSmallSuccess_0007
261 * @tc.desc : Mremap maps with flag 0 from large memory to small successfully.
262 * @tc.size : MediumTest
263 * @tc.type : Function
264 * @tc.level : Level 2
265 */
266 HWTEST_F(HatsMmapSyscallTest, MremapSyscallToSmallSuccess_0007, Function | MediumTest | Level2)
267 {
268 size_t size = 4096;
269 size_t newSize = 2048;
270 void *va = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
271 EXPECT_NE(va, MAP_FAILED);
272
273 void* vaNew = mremap(va, size, newSize, 0);
274 EXPECT_NE(vaNew, MAP_FAILED);
275
276 int ret = munmap(va, size);
277 EXPECT_EQ(ret, 0);
278
279 ret = munmap(vaNew, newSize);
280 EXPECT_EQ(ret, 0);
281 }
282
283 /*
284 * @tc.number : SUB_KERNEL_SYSCALL_MMAPSYSCALL_0800
285 * @tc.name : MremapSyscallMoveSuccess_0008
286 * @tc.desc : Mremap maps with flag MREMAP_MAYMOVE from small memory to large successfully.
287 * @tc.size : MediumTest
288 * @tc.type : Function
289 * @tc.level : Level 2
290 */
291 HWTEST_F(HatsMmapSyscallTest, MremapSyscallMoveSuccess_0008, Function | MediumTest | Level2)
292 {
293 size_t size = SIZE_1M;
294 size_t newSize = 2048;
295 void *va = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
296 EXPECT_NE(va, MAP_FAILED);
297
298 void* vaNew = mremap(va, size, newSize, MREMAP_MAYMOVE);
299 EXPECT_NE(vaNew, MAP_FAILED);
300
301 int ret = munmap(va, size);
302 EXPECT_EQ(ret, 0);
303
304 ret = munmap(vaNew, newSize);
305 EXPECT_EQ(ret, 0);
306 }
307