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