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