1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
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 <stdlib.h>
17 #include <string.h>
18 #include <stdio.h>
19 #include <errno.h>
20 #include <sys/mman.h>
21 #include <sys/file.h>
22 #include <sys/types.h>
23 #include <fcntl.h>
24 #include <unistd.h>
25 #include <gtest/gtest.h>
26 
27 #include "log.h"
28 #include "utils.h"
29 #include "KernelConstants.h"
30 
31 using namespace testing::ext;
32 
33 #define MMAP_TESTFILE "/storage/testMmap.txt"
34 
35 class MmapApiTest : public testing::Test {
36 };
37 
38 /**
39  * @tc.number SUB_KERNEL_MEM_MMAP_0100
40  * @tc.name   mmap function anonymous private map and read and write permission test
41  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
42  */
HWTEST_F(MmapApiTest, testMmapAnonPrivate, Function | MediumTest | Level3)43 HWTEST_F(MmapApiTest, testMmapAnonPrivate, Function | MediumTest | Level3)
44 {
45     size_t len = PAGE_SIZE;
46     int sum = 0;
47     char testChar = 'A';
48     int prot = PROT_READ | PROT_WRITE;
49     int flags = MAP_ANONYMOUS | MAP_PRIVATE;
50 
51     char *mem = (char *)mmap(nullptr, len, prot, flags, -1, 0);
52     ASSERT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
53 
54     for (size_t i = 0; i < len; i++) {
55         sum += mem[i];
56     }
57     ASSERT_TRUE(sum == 0) << "sum != 0, sum = " << sum;
58 
59     pid_t pid = fork();
60     EXPECT_TRUE(pid >= 0) << "Fork Error";
61     if (pid == 0) {
62         mem[0] = testChar;
63         mem[1] = testChar + 3;
64         LOG("child: mem[0] = %c (0x%02x)", mem[0], mem[0]);
65         LOG("child: mem[1] = %c (0x%02x)", mem[1], mem[1]);
66         exit(0);
67     } else {
68         WaitProcExitedOK(pid);
69         LOG("parent: mem[0] = %c (0x%02x)", mem[0], mem[0]);
70         LOG("parent: mem[1] = %c (0x%02x)", mem[1], mem[1]);
71 
72         EXPECT_TRUE(mem[0] != testChar) << "mem[0] = " << mem[0];
73         EXPECT_TRUE(mem[1] != (testChar + 3)) << "mem[1] = " << mem[1];
74         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
75     }
76 }
77 
78 /**
79  * @tc.number SUB_KERNEL_MEM_MMAP_0200
80  * @tc.name   mmap function anonymous share map and read and write permission test
81  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
82  */
HWTEST_F(MmapApiTest, testMmapAnonShare, Function | MediumTest | Level3)83 HWTEST_F(MmapApiTest, testMmapAnonShare, Function | MediumTest | Level3)
84 {
85     size_t len = PAGE_SIZE;
86     char testChar = 'A';
87     int prot = PROT_READ | PROT_WRITE;
88     int flags = MAP_ANONYMOUS | MAP_SHARED;
89 
90     char *mem = (char *)mmap(nullptr, len, prot, flags, -1, 0);
91     ASSERT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
92 
93     pid_t pid = fork();
94     EXPECT_TRUE(pid >= 0) << "Fork Error";
95     if (pid == 0) {
96         mem[0] = testChar;
97         mem[1] = testChar + 3;
98         LOG("child: mem[0] = %c (0x%02x)", mem[0], mem[0]);
99         LOG("child: mem[1] = %c (0x%02x)", mem[1], mem[1]);
100         exit(0);
101     } else {
102         WaitProcExitedOK(pid);
103         LOG("parent: mem[0] = %c (0x%02x)", mem[0], mem[0]);
104         LOG("parent: mem[1] = %c (0x%02x)", mem[1], mem[1]);
105         // not support at present, suggest shm, after support need change to ==
106         EXPECT_TRUE(mem[0] != testChar) << "mem[0] = " << mem[0];
107         EXPECT_TRUE(mem[1] != (testChar + 3)) << "mem[1] = " << mem[1];
108         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
109     }
110 }
111 
112 /**
113  * @tc.number SUB_KERNEL_MEM_MMAP_0300
114  * @tc.name   mmap function anonymous share map and only read permission test
115  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
116  */
HWTEST_F(MmapApiTest, testMmapAnonShareOnlyRead, Function | MediumTest | Level1)117 HWTEST_F(MmapApiTest, testMmapAnonShareOnlyRead, Function | MediumTest | Level1)
118 {
119     size_t len = PAGE_SIZE;
120     char testChar = 'A';
121     int prot = PROT_READ;
122     int flags = MAP_ANONYMOUS | MAP_SHARED;
123 
124     char *mem = (char *)mmap(nullptr, len, prot, flags, -1, 0);
125     ASSERT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
126 
127     pid_t pid = fork();
128     EXPECT_TRUE(pid >= 0) << "Fork Error";
129     if (pid == 0) {
130         /* Only read permit and write data to this area cause process crash */
131         mem[0] = testChar;
132         mem[1] = testChar + 3;
133         exit(0);
134     } else {
135         ExpectProcCrashed(pid);
136 
137         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
138     }
139 }
140 
141 /**
142  * @tc.number SUB_KERNEL_MEM_MMAP_0400
143  * @tc.name   mmap function anonymous share map and only write permission test
144  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
145  */
HWTEST_F(MmapApiTest, testMmapAnonShareOnlyWrite, Function | MediumTest | Level3)146 HWTEST_F(MmapApiTest, testMmapAnonShareOnlyWrite, Function | MediumTest | Level3)
147 {
148     size_t len = PAGE_SIZE;
149     int prot = PROT_WRITE;
150     int flags = MAP_ANONYMOUS | MAP_SHARED;
151 
152     char *mem = (char *)mmap(nullptr, len, prot, flags, -1, 0);
153     LOG("mem = %p", mem);
154     ASSERT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
155 
156     pid_t pid = fork();
157     EXPECT_TRUE(pid >= 0) << "Fork Error";
158     if (pid == 0) {
159         char testChar = 'A';
160         mem[0] = testChar;
161         mem[1] = testChar + 3;
162 
163         LOG("mem[0] = 0x%02x", mem[0]);
164         LOG("mem[1] = 0x%02x", mem[1]);
165         exit(0);
166     } else {
167         WaitProcExitedOK(pid);
168         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
169     }
170 }
171 
172 /**
173  * @tc.number SUB_KERNEL_MEM_MMAP_0500
174  * @tc.name   mmap function anonymous private map and execute permission test
175  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
176  */
HWTEST_F(MmapApiTest, testMmapAnonPrivateExec, Function | MediumTest | Level4)177 HWTEST_F(MmapApiTest, testMmapAnonPrivateExec, Function | MediumTest | Level4)
178 {
179     char *mem = nullptr;
180     size_t len = PAGE_SIZE / 4;
181     size_t i;
182     int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
183     int flags = MAP_ANONYMOUS | MAP_PRIVATE;
184     int (*fun)(void);
185 
186     mem = (char *)mmap(nullptr, len, prot, flags, -1, 0);
187     ASSERT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
188 
189     unsigned long fnReturnFive[] = {0xe52db004, 0xe28db000, 0xe3a03005,
190                                     0xe1a00003, 0xe28bd000, 0xe49db004, 0xe12fff1e};
191     char *ptr = (char *)fnReturnFive;
192 
193     for (i = 0; i < sizeof(fnReturnFive); i++) {
194         mem[i] = ptr[i];
195     }
196 
197     for (i = 0; i < 30; i++) {
198         printf("%02x ", mem[i]);
199     }
200     printf("\r\n");
201 
202     pid_t pid = fork();
203     EXPECT_TRUE(pid >= 0) << "Fork Error";
204     if (pid == 0) {
205         fun = (int (*)(void))mem;
206         int five = fun();
207         LOG("five = 0x%02x", five);
208 
209         if (five == 0x05) {
210             exit(0);
211         }
212         exit(-1);
213     } else {
214         WaitProcExitedOK(pid);
215 
216         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
217     }
218 }
219 
220 /**
221  * @tc.number SUB_KERNEL_MEM_MMAP_0600
222  * @tc.name   mmap function anonymous share map and execute permission test
223  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
224  */
HWTEST_F(MmapApiTest, testMmapAnonShareExec, Function | MediumTest | Level4)225 HWTEST_F(MmapApiTest, testMmapAnonShareExec, Function | MediumTest | Level4)
226 {
227     char *mem = nullptr;
228     size_t len = PAGE_SIZE / 4;
229     size_t i;
230     int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
231     int flags = MAP_ANONYMOUS | MAP_SHARED;
232     int (*fun)(void);
233 
234     mem = (char *)mmap(nullptr, len, prot, flags, -1, 0);
235     ASSERT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
236 
237     unsigned long fnReturnFive[] = {0xe52db004, 0xe28db000, 0xe3a03005,
238                                     0xe1a00003, 0xe28bd000, 0xe49db004, 0xe12fff1e};
239     char *ptr = (char *)fnReturnFive;
240 
241     for (i = 0; i < sizeof(fnReturnFive); i++) {
242         mem[i] = ptr[i];
243     }
244 
245     for (i = 0; i < 30; i++) {
246         printf("%02x ", mem[i]);
247     }
248     printf("\r\n");
249 
250     pid_t pid = fork();
251     EXPECT_TRUE(pid >= 0) << "Fork Error";
252 
253     if (pid == 0) {
254         fun = (int (*)(void))mem;
255         int five = fun();
256         LOG("five = 0x%02x", five);
257 
258         if (five == 0x05) {
259             exit(0);
260         }
261         exit(-1);
262     } else {
263         WaitProcExitedOK(pid);
264 
265         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
266     }
267 }
268 
269 /**
270  * @tc.number SUB_KERNEL_MEM_MMAP_0700
271  * @tc.name   mmap function anonymous share map and NO execute permission test
272  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
273  */
HWTEST_F(MmapApiTest, testMmapAnonShareNoExec, Function | MediumTest | Level2)274 HWTEST_F(MmapApiTest, testMmapAnonShareNoExec, Function | MediumTest | Level2)
275 {
276     char *mem = nullptr;
277     size_t len = PAGE_SIZE / 4;
278     size_t i;
279     int prot = PROT_READ | PROT_WRITE;
280     int flags = MAP_ANONYMOUS | MAP_SHARED;
281     int (*fun)(void);
282 
283     mem = (char *)mmap(nullptr, len, prot, flags, -1, 0);
284     ASSERT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
285 
286     unsigned long fnReturnFive[] = {0xe52db004, 0xe28db000, 0xe3a03005,
287                                     0xe1a00003, 0xe28bd000, 0xe49db004, 0xe12fff1e};
288     char *ptr = (char *)fnReturnFive;
289 
290     for (i = 0; i < sizeof(fnReturnFive); i++) {
291         mem[i] = ptr[i];
292     }
293 
294     pid_t pid = fork();
295     EXPECT_TRUE(pid >= 0) << "Fork Error";
296 
297     if (pid == 0) {
298         fun = (int (*)(void))mem;
299         int five = fun();
300         LOG("five = 0x%02x", five);
301 
302         exit(0);
303     } else {
304         ExpectProcCrashed(pid);
305 
306         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
307     }
308 }
309 
310 /**
311  * @tc.number SUB_KERNEL_MEM_MMAP_0800
312  * @tc.name   mmap function file private map and read and write permission test
313  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
314  */
HWTEST_F(MmapApiTest, testMmapFilePrivate, Function | MediumTest | Level3)315 HWTEST_F(MmapApiTest, testMmapFilePrivate, Function | MediumTest | Level3)
316 {
317     const size_t len = PAGE_SIZE;
318     char testChar = 'A';
319     int prot = PROT_READ | PROT_WRITE;
320     int flags = MAP_PRIVATE;
321     char buf[PAGE_SIZE] = {0};
322     char file[] = MMAP_TESTFILE;
323 
324     int fd = open(file, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
325     ASSERT_TRUE(fd != -1) << "ERROR: open() == -1";
326 
327     int wByte = write(fd, buf, len);
328     EXPECT_TRUE(wByte > 0) << "ERROR: write() <= 0";
329 
330     char *mem = (char *)mmap(nullptr, len, prot, flags, fd, 0);
331     ASSERT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
332 
333     pid_t pid = fork();
334     EXPECT_TRUE(pid >= 0) << "Fork Error";
335 
336     if (pid == 0) {
337         mem[0] = testChar;
338         mem[1] = testChar + 3;
339         exit(0);
340     } else {
341         WaitProcExitedOK(pid);
342 
343         LOG("mem[0] = %c (0x%02x)", mem[0], mem[0]);
344         LOG("mem[1] = %c (0x%02x)", mem[1], mem[1]);
345 
346         EXPECT_TRUE(mem[0] != testChar) << "mem[0] = " << mem[0];
347         EXPECT_TRUE(mem[1] != (testChar + 3)) << "mem[1] = " << mem[1];
348         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
349 
350         EXPECT_TRUE(close(fd) != -1) << "ERROR: close() == -1";
351         Msleep(1000);
352         EXPECT_TRUE(remove(file) == 0) << "ERROR: remove() != 0" << errno;
353     }
354 }
355 
356 /**
357  * @tc.number SUB_KERNEL_MEM_MMAP_0900
358  * @tc.name   mmap function file share map and read and write permission test
359  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
360  */
HWTEST_F(MmapApiTest, testMmapFileShare, Function | MediumTest | Level3)361 HWTEST_F(MmapApiTest, testMmapFileShare, Function | MediumTest | Level3)
362 {
363     const size_t len = PAGE_SIZE;
364     char testChar = 'A';
365     int prot = PROT_READ | PROT_WRITE;
366     int flags = MAP_SHARED;
367     char buf[PAGE_SIZE] = {0};
368     char file[] = MMAP_TESTFILE;
369 
370     int fd = open(file, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
371     ASSERT_TRUE(fd != -1) << "ERROR: open() == -1";
372 
373     int wByte = write(fd, buf, len);
374     EXPECT_TRUE(wByte > 0) << "ERROR: write() <= 0";
375 
376     char *mem = (char *)mmap(nullptr, len, prot, flags, fd, 0);
377     ASSERT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
378 
379     pid_t pid = fork();
380     EXPECT_TRUE(pid >= 0) << "Fork Error";
381 
382     if (pid == 0) {
383         mem[0] = testChar;
384         mem[1] = testChar + 3;
385         exit(0);
386     } else {
387         WaitProcExitedOK(pid);
388 
389         LOG("mem[0] = %c (0x%02x)", mem[0], mem[0]);
390         LOG("mem[1] = %c (0x%02x)", mem[1], mem[1]);
391 
392         EXPECT_TRUE(mem[0] == testChar) << "mem[0] = " << mem[0];
393         EXPECT_TRUE(mem[1] == (testChar + 3)) << "mem[1] = " << mem[1];
394         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
395 
396         EXPECT_TRUE(close(fd) != -1) << "ERROR: close() == -1";
397         Msleep(1000);
398         EXPECT_TRUE(remove(file) == 0) << "ERROR: remove() != 0" << errno;
399     }
400 }
401 
402 /**
403  * @tc.number SUB_KERNEL_MEM_MMAP_1000
404  * @tc.name   mmap function file share map and only read permission test
405  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
406  */
HWTEST_F(MmapApiTest, testMmapFileShareOnlyRead, Function | MediumTest | Level1)407 HWTEST_F(MmapApiTest, testMmapFileShareOnlyRead, Function | MediumTest | Level1)
408 {
409     const size_t len = PAGE_SIZE;
410     char testChar = 'A';
411     int prot = PROT_READ;
412     int flags = MAP_SHARED;
413     char buf[PAGE_SIZE] = {0};
414     char file[] = MMAP_TESTFILE;
415     int fd = open(file, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
416     ASSERT_TRUE(fd != -1) << "ERROR: open() == -1";
417 
418     int wByte = write(fd, buf, len);
419     EXPECT_TRUE(wByte > 0) << "ERROR: write() <= 0";
420 
421     char *mem = (char *)mmap(nullptr, len, prot, flags, fd, 0);
422     ASSERT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
423 
424     pid_t pid = fork();
425     EXPECT_TRUE(pid >= 0) << "Fork Error";
426 
427     if (pid == 0) {
428         /* Only read permit and write data to this area cause process crash */
429         mem[0] = testChar;
430         mem[1] = testChar + 3;
431 
432         exit(0);
433     } else {
434         ExpectProcCrashed(pid);
435 
436         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
437         EXPECT_TRUE(close(fd) != -1) << "ERROR: close() == -1";
438         Msleep(1000);
439         EXPECT_TRUE(remove(file) == 0) << "ERROR: remove() != 0" << errno;
440     }
441 }
442 
443 /**
444  * @tc.number SUB_KERNEL_MEM_MMAP_1100
445  * @tc.name   mmap function file share map and only write permission test
446  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
447  */
HWTEST_F(MmapApiTest, testMmapFileShareOnlyWrite, Function | MediumTest | Level3)448 HWTEST_F(MmapApiTest, testMmapFileShareOnlyWrite, Function | MediumTest | Level3)
449 {
450     const size_t len = PAGE_SIZE;
451     int prot = PROT_WRITE;
452     int flags = MAP_SHARED;
453     char buf[PAGE_SIZE] = {0};
454     char file[] = MMAP_TESTFILE;
455 
456     int fd = open(file, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
457     ASSERT_TRUE(fd != -1) << "ERROR: open() == -1";
458 
459     int wByte = write(fd, buf, len);
460     EXPECT_TRUE(wByte > 0) << "ERROR: write() <= 0";
461 
462     char *mem = (char *)mmap(nullptr, len, prot, flags, fd, 0);
463     ASSERT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
464 
465     pid_t pid = fork();
466     EXPECT_TRUE(pid >= 0) << "Fork Error";
467 
468     if (pid == 0) {
469         char testChar = 'A';
470         mem[0] = testChar;
471         mem[1] = testChar + 3;
472 
473         LOG("mem[0] = 0x%02x", mem[0]);
474         LOG("mem[1] = 0x%02x", mem[1]);
475         exit(0);
476     } else {
477         WaitProcExitedOK(pid);
478 
479         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
480         EXPECT_TRUE(close(fd) != -1) << "ERROR: close() == -1";
481         Msleep(1000);
482         EXPECT_TRUE(remove(file) == 0) << "ERROR: remove() != 0" << errno;
483     }
484 }
485 
486 /**
487  * @tc.number SUB_KERNEL_MEM_MMAP_1200
488  * @tc.name   mmap function file private map and execute permission test
489  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
490  */
HWTEST_F(MmapApiTest, testMmapFilePrivateExec, Function | MediumTest | Level4)491 HWTEST_F(MmapApiTest, testMmapFilePrivateExec, Function | MediumTest | Level4)
492 {
493     char *mem = nullptr;
494     size_t len = PAGE_SIZE / 4;
495     int prot = PROT_READ | PROT_EXEC;
496     int flags = MAP_PRIVATE;
497     int (*fun)(void);
498     unsigned long fnReturnFive[] = {0xe52db004, 0xe28db000, 0xe3a03005,
499                                     0xe1a00003, 0xe28bd000, 0xe49db004, 0xe12fff1e};
500     char file[] = MMAP_TESTFILE;
501 
502     int fd = open(file, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
503     ASSERT_TRUE(fd != -1) << "ERROR: open() == -1";
504 
505     int wByte = write(fd, fnReturnFive, sizeof(fnReturnFive));
506     EXPECT_TRUE(wByte > 0) << "ERROR: write() <= 0";
507 
508     mem = (char *)mmap(nullptr, len, prot, flags, fd, 0);
509     EXPECT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
510 
511     pid_t pid = fork();
512     EXPECT_TRUE(pid >= 0) << "Fork Error";
513 
514     if (pid == 0) {
515         fun = (int (*)(void))mem;
516         int five = fun();
517         LOG("five = 0x%02x", five);
518 
519         if (five == 0x05) {
520             exit(0);
521         }
522         exit(-1);
523     } else {
524         WaitProcExitedOK(pid);
525 
526         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
527         EXPECT_TRUE(close(fd) != -1) << "ERROR: close() == -1";
528         Msleep(1000);
529         EXPECT_TRUE(remove(file) == 0) << "ERROR: remove() != 0" << errno;
530     }
531 }
532 
533 /**
534  * @tc.number SUB_KERNEL_MEM_MMAP_1300
535  * @tc.name   mmap function file share map and execute permission test
536  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
537  */
HWTEST_F(MmapApiTest, testMmapFileShareExec, Function | MediumTest | Level4)538 HWTEST_F(MmapApiTest, testMmapFileShareExec, Function | MediumTest | Level4)
539 {
540     char *mem = nullptr;
541     size_t len = PAGE_SIZE / 4;
542     int prot = PROT_READ | PROT_EXEC;
543     int flags = MAP_SHARED;
544     int (*fun)(void);
545     unsigned long fnReturnFive[] = {0xe52db004, 0xe28db000, 0xe3a03005,
546                                     0xe1a00003, 0xe28bd000, 0xe49db004, 0xe12fff1e};
547     char file[] = MMAP_TESTFILE;
548 
549     int fd = open(file, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
550     ASSERT_TRUE(fd != -1) << "ERROR: open() == -1";
551 
552     int wByte = write(fd, fnReturnFive, sizeof(fnReturnFive));
553     EXPECT_TRUE(wByte > 0) << "ERROR: write() <= 0";
554 
555     mem = (char *)mmap(nullptr, len, prot, flags, fd, 0);
556     EXPECT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
557 
558     pid_t pid = fork();
559     EXPECT_TRUE(pid >= 0) << "Fork Error";
560 
561     if (pid == 0) {
562         fun = (int (*)(void))mem;
563         int five = fun();
564         LOG("five = 0x%02x", five);
565 
566         if (five == 0x05) {
567             exit(0);
568         }
569         exit(-1);
570     } else {
571         WaitProcExitedOK(pid);
572 
573         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
574         EXPECT_TRUE(close(fd) != -1) << "ERROR: close() == -1";
575         Msleep(1000);
576         EXPECT_TRUE(remove(file) == 0) << "ERROR: remove() != 0" << errno;
577     }
578 }
579 
580 /**
581  * @tc.number SUB_KERNEL_MEM_MMAP_1400
582  * @tc.name   mmap function file share map and NO execute permission test
583  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
584  */
HWTEST_F(MmapApiTest, testMmapFileShareNoExec, Function | MediumTest | Level2)585 HWTEST_F(MmapApiTest, testMmapFileShareNoExec, Function | MediumTest | Level2)
586 {
587     char *mem = nullptr;
588     size_t len = PAGE_SIZE / 4;
589     int prot = PROT_READ;
590     int flags = MAP_SHARED;
591     int (*fun)(void);
592     unsigned long fnReturnFive[] = {0xe52db004, 0xe28db000, 0xe3a03005,
593                                     0xe1a00003, 0xe28bd000, 0xe49db004, 0xe12fff1e};
594     char file[] = MMAP_TESTFILE;
595 
596     int fd = open(file, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
597     ASSERT_TRUE(fd != -1) << "ERROR: open() == -1";
598 
599     int wByte = write(fd, fnReturnFive, sizeof(fnReturnFive));
600     EXPECT_TRUE(wByte > 0) << "ERROR: write() <= 0";
601 
602     mem = (char *)mmap(nullptr, len, prot, flags, fd, 0);
603     EXPECT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
604 
605     pid_t pid = fork();
606     EXPECT_TRUE(pid >= 0) << "Fork Error";
607 
608     if (pid == 0) {
609         fun = (int (*)(void))mem;
610         int five = fun();
611         LOG("five = 0x%02x", five);
612 
613         exit(0);
614     } else {
615         ExpectProcCrashed(pid);
616 
617         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
618         EXPECT_TRUE(close(fd) != -1) << "ERROR: close() == -1";
619         Msleep(1000);
620         EXPECT_TRUE(remove(file) == 0) << "ERROR: remove() != 0" << errno;
621     }
622 }
623 
624 /**
625  * @tc.number SUB_KERNEL_MEM_MMAP_1500
626  * @tc.name   mmap function overlay map test
627  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
628  */
HWTEST_F(MmapApiTest, testMmapOverlay, Function | MediumTest | Level3)629 HWTEST_F(MmapApiTest, testMmapOverlay, Function | MediumTest | Level3)
630 {
631     int i;
632     void *addr[3];
633     size_t len = 0x00200000;
634     unsigned long fixAddr = 0x24000000UL;
635 
636     for (i = 0; i < 3; i++) {
637         addr[i] = nullptr;
638     }
639 
640     void *mem = mmap((void *)fixAddr, len, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
641     LOG("mem = %p, mem + len = %p", mem, (char *)mem + len);
642     EXPECT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
643     addr[0] = mem;
644 
645     unsigned long before = fixAddr - 0x00100000;
646     void *prev = mmap((void *)before, len, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
647     LOG("prev = %p, prev + len = %p", prev, (char *)prev + len);
648     EXPECT_TRUE(prev != MAP_FAILED) << "mem != MAP_FAILED";
649     EXPECT_TRUE(prev != mem) << "prev == mem";
650     addr[1] = prev;
651 
652     unsigned long after = fixAddr + 0x00100000;
653     void *next = mmap((void *)after, len, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
654     LOG("next = %p, next + len = %p", next, (char *)next + len);
655     EXPECT_TRUE(next != MAP_FAILED) << "mem != MAP_FAILED";
656 
657     for (i = 0; i < 2; i++) {
658         if (next == addr[i]) {
659             break;
660         }
661     }
662     EXPECT_EQ(i, 2) << "i != 2";
663     addr[2] = next;
664 
665     size_t small = len - 0x00100000;
666     void *belong = mmap((void *)after, small, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
667     LOG("belong = %p, belong + shinkLen = %p", belong, (char *)belong + small);
668     EXPECT_TRUE(belong != MAP_FAILED) << "belong != MAP_FAILED";
669 
670     for (i = 0; i < 3; i++) {
671         LOG("belong = %p, addr[%d] = %p", belong, i, addr[i]);
672         if (belong == addr[i]) {
673             break;
674         }
675     }
676     EXPECT_EQ(i, 3) << "i != 3";
677 
678     if (belong != MAP_FAILED) {
679         EXPECT_TRUE(munmap(belong, small) == 0) << "ERROR: munmap() != 0";
680     }
681 
682     if (next != MAP_FAILED) {
683         EXPECT_TRUE(munmap(next, len) == 0) << "ERROR: munmap() != 0";
684     }
685 
686     if (prev != MAP_FAILED) {
687         EXPECT_TRUE(munmap(prev, len) == 0) << "ERROR: munmap() != 0";
688     }
689 
690     if (mem != MAP_FAILED) {
691         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
692     }
693 }
694 
695 /**
696  * @tc.number SUB_KERNEL_MEM_MMAP_1600
697  * @tc.name   mmap function write back to the file test
698  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
699  */
HWTEST_F(MmapApiTest, testMmapWriteBack, Function | MediumTest | Level3)700 HWTEST_F(MmapApiTest, testMmapWriteBack, Function | MediumTest | Level3)
701 {
702     char testChar = 'A';
703     size_t i, len = PAGE_SIZE;
704     int failure = 0;
705     int bufSize = len / 4;
706     char wBuffer[PAGE_SIZE / 4];
707     char rBuffer[PAGE_SIZE / 4];
708     char file[] = MMAP_TESTFILE;
709 
710     int fd = open(file, O_CREAT | O_RDWR, 0777);
711     ASSERT_TRUE(fd != -1) << "ERROR: open() == -1";
712 
713     for (i = 0; i < (size_t)bufSize; i++) {
714         rBuffer[i] = 0;
715         wBuffer[i] = '0';
716     }
717 
718     EXPECT_TRUE(write(fd, wBuffer, bufSize) == bufSize) << "ERROR: write() != bufSize";
719 
720     void *mem = mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
721     LOG("TAG1 mem = %p", mem);
722     EXPECT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
723 
724     memset(mem, testChar, len);
725 
726     char *ptr = (char *)mem;
727     for (i = 0; i < len; i++) {
728         if (ptr[i] != testChar) {
729             failure = 1;
730             break;
731         }
732     }
733     EXPECT_TRUE(failure == 0) << "i = " << i << ", ptr = " << ptr[i];
734 
735     EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
736     EXPECT_TRUE(close(fd) != -1) << "ERROR: close() == -1";
737 
738     fd = open(file, O_RDONLY, 0777);
739     EXPECT_TRUE(fd != -1) << "ERROR: open() == -1";
740 
741     EXPECT_TRUE(read(fd, rBuffer, bufSize) == bufSize) << "ERROR: read() != bufSize";
742 
743     failure = 0;
744     for (i = 0; i < (size_t)bufSize; i++) {
745         if (rBuffer[i] != testChar) {
746             failure = 1;
747             break;
748         }
749     }
750     EXPECT_TRUE(failure == 0) << "i = " << i << ", rBuffer = " << rBuffer[i];
751 
752     EXPECT_TRUE(close(fd) != -1) << "ERROR: close() == -1";
753     Msleep(1000);
754     EXPECT_TRUE(remove(file) == 0) << "ERROR: remove() != 0" << errno;
755 }
756 
757 /**
758  * @tc.number SUB_KERNEL_MEM_MMAP_1700
759  * @tc.name   mmap function errno for EACCES test
760  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
761  */
HWTEST_F(MmapApiTest, testMmapEACCES, Function | MediumTest | Level3)762 HWTEST_F(MmapApiTest, testMmapEACCES, Function | MediumTest | Level3)
763 {
764     int fd;
765     void *mem = nullptr;
766     size_t len = PAGE_SIZE;
767     char file[] = MMAP_TESTFILE;
768 
769     /* file open read only access mode */
770     fd = open(file, O_CREAT | O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO);
771     ASSERT_TRUE(fd != -1) << "ERROR: open() == -1";
772 
773     mem = mmap(nullptr, len, PROT_WRITE, MAP_SHARED, fd, 0);
774     EXPECT_TRUE(mem == MAP_FAILED) << "mem != MAP_FAILED, mem = " << mem;
775     EXPECT_TRUE(errno == EACCES) << "ERROR: errno != EACCES, errno = " << errno << " EACCES = " << EACCES;
776 
777     if (mem != MAP_FAILED) {
778         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
779     }
780     EXPECT_TRUE(close(fd) != -1) << "ERROR: close() == -1";
781 
782     /* file open append access mode */
783     fd = open(file, O_APPEND, S_IRWXU | S_IRWXG | S_IRWXO);
784     EXPECT_TRUE(fd != -1) << "ERROR: open() == -1";
785 
786     mem = mmap(nullptr, len, PROT_WRITE, MAP_SHARED, fd, 0);
787     EXPECT_TRUE(mem == MAP_FAILED) << "mem != MAP_FAILED, mem = " << mem;
788     EXPECT_TRUE(errno == EACCES) << "ERROR: errno != EACCES, errno = " << errno << " EACCES = " << EACCES;
789 
790     if (mem != MAP_FAILED) {
791         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
792     }
793     EXPECT_TRUE(close(fd) != -1) << "ERROR: close() == -1";
794     Msleep(1000);
795     EXPECT_TRUE(remove(file) == 0) << "ERROR: remove() != 0" << errno;
796 }
797 
798 /**
799  * @tc.number SUB_KERNEL_MEM_MMAP_1800
800  * @tc.name   mmap function errno for EBADF test
801  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
802  */
HWTEST_F(MmapApiTest, testMmapEBADF, Function | MediumTest | Level3)803 HWTEST_F(MmapApiTest, testMmapEBADF, Function | MediumTest | Level3)
804 {
805     void *mem = nullptr;
806     size_t len = PAGE_SIZE;
807     char file[] = MMAP_TESTFILE;
808     int flags[] = {MAP_PRIVATE, MAP_SHARED};
809 
810     int fd = open(file, O_CREAT | O_RDWR, 0777);
811     ASSERT_TRUE(fd != -1) << "ERROR: open() == -1";
812     EXPECT_TRUE(close(fd) != -1) << "ERROR: close() == -1";
813 
814     for (int i = 0; i < 2; i++) {
815         mem = mmap(nullptr, len, PROT_READ | PROT_WRITE, flags[i], fd, 0);
816         EXPECT_TRUE(mem == MAP_FAILED) << "mem == MAP_FAILED";
817         EXPECT_TRUE(errno == EBADF) << "ERROR: errno != EBADF, errno = " << errno << " EBADF = " << EBADF;
818 
819         if (mem != MAP_FAILED) {
820             EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
821         }
822     }
823 
824     EXPECT_TRUE(remove(file) == 0) << "ERROR: remove() != 0";
825 }
826 
827 /**
828  * @tc.number SUB_KERNEL_MEM_MMAP_1900
829  * @tc.name   mmap function errno for EINVAL test
830  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
831  */
HWTEST_F(MmapApiTest, testMmapEINVAL, Function | MediumTest | Level3)832 HWTEST_F(MmapApiTest, testMmapEINVAL, Function | MediumTest | Level3)
833 {
834     void *mem = nullptr;
835     size_t len = PAGE_SIZE;
836     char file[] = MMAP_TESTFILE;
837 
838     int fd = open(file, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
839     ASSERT_TRUE(fd != -1) << "ERROR: open() == -1";
840 
841     void *invalueAddr = (void *)(0x21f20000 | 0x123);
842     mem = mmap(invalueAddr, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0);
843     EXPECT_TRUE(mem == MAP_FAILED) << "mem != MAP_FAILED, mem = " << mem;
844     EXPECT_TRUE(errno == EINVAL) << "ERROR: errno != EINVAL, errno = " << errno << " EINVAL = " << EINVAL;
845 
846     if (mem != MAP_FAILED) {
847         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
848     }
849 
850     len = 0x40000000;
851     mem = mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
852     EXPECT_TRUE(mem == MAP_FAILED) << "mem != MAP_FAILED, mem = " << mem;
853     EXPECT_TRUE(errno == EINVAL) << "ERROR: errno != EINVAL, errno = " << errno << " EINVAL = " << EINVAL;
854 
855     if (mem != MAP_FAILED) {
856         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
857     }
858 
859     len = PAGE_SIZE;
860     mem = mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0xFFFFFFFF);
861     EXPECT_TRUE(mem == MAP_FAILED) << "mem != MAP_FAILED, mem = " << mem;
862     EXPECT_TRUE(errno == EINVAL) << "ERROR: errno != EINVAL, errno = " << errno << " EINVAL = " << EINVAL;
863 
864     if (mem != MAP_FAILED) {
865         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
866     }
867 
868     len = 0;
869     mem = mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
870     EXPECT_TRUE(mem == MAP_FAILED) << "mem != MAP_FAILED, mem = " << mem;
871     EXPECT_TRUE(errno == EINVAL) << "ERROR: errno != EINVAL, errno = " << errno << " EINVAL = " << EINVAL;
872 
873     if (mem != MAP_FAILED) {
874         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
875     }
876 
877     len = PAGE_SIZE;
878     mem = mmap(nullptr, len, 0, MAP_SHARED, fd, 0);
879     EXPECT_TRUE(mem != MAP_FAILED) << "mem != MAP_FAILED, mem = " << mem;
880 
881     if (mem != MAP_FAILED) {
882         EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
883     }
884 
885     int flags[3] = {0, MAP_ANON, MAP_PRIVATE | MAP_SHARED};
886 
887     len = PAGE_SIZE;
888     for (int i = 0; i < 3; i++) {
889         mem = mmap(nullptr, len, PROT_READ | PROT_WRITE, flags[i], fd, 0);
890         EXPECT_TRUE(mem == MAP_FAILED) << "mem != MAP_FAILED, mem = " << mem;
891         EXPECT_TRUE(errno == EINVAL) << "ERROR: errno != EINVAL, errno = " << errno << " EINVAL = " << EINVAL;
892 
893         if (mem != MAP_FAILED) {
894             EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
895         }
896     }
897 
898     EXPECT_TRUE(close(fd) != -1) << "ERROR: close() == -1";
899     Msleep(1000);
900     EXPECT_TRUE(remove(file) == 0) << "ERROR: remove() != 0" << errno;
901 }
902 
903 /**
904  * @tc.number SUB_KERNEL_MEM_MMAP_2000
905  * @tc.name   mmap function errno for ENOMEM test
906  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
907  */
HWTEST_F(MmapApiTest, testMmapENOMEM, Function | MediumTest | Level3)908 HWTEST_F(MmapApiTest, testMmapENOMEM, Function | MediumTest | Level3)
909 {
910     pid_t pid = fork();
911     ASSERT_TRUE(pid >= 0) << "Fork Error";
912 
913     if (pid == 0) {
914         int i, k, ret;
915         void *mem[100];
916         size_t len = 0x1000000;
917         int flags = MAP_ANONYMOUS | MAP_PRIVATE;
918 
919         for (i = 0; i < 100; i++) {
920             mem[i] = mmap(nullptr, len, PROT_READ | PROT_WRITE, flags, -1, 0);
921             if (mem[i] == MAP_FAILED) {
922                 LOG("MAP_FAILED: i = %d, errno = %d, ENOMEM = %d", i, errno, ENOMEM);
923                 break;
924             }
925         }
926 
927         ret = 0;
928         if (i == 100 || mem[i] != MAP_FAILED || errno != ENOMEM) {
929             ret = 1;
930             LOG("ERROR: i = %d, mem[i] = %p, MAP_FAILED = %d, errno = %d", i, mem[i], MAP_FAILED, errno);
931         }
932 
933         for (k = 0; k < i; k++) {
934             munmap(mem[k], len);
935         }
936         exit(ret);
937     } else {
938         WaitProcExitedOK(pid);
939     }
940 }
941 
942 
943 /**
944  * @tc.number SUB_KERNEL_MEM_MUNMAP_0100
945  * @tc.name   munmap function errno for EINVAL test
946  * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
947  */
HWTEST_F(MmapApiTest, testMunmapEINVAL, Function | MediumTest | Level3)948 HWTEST_F(MmapApiTest, testMunmapEINVAL, Function | MediumTest | Level3)
949 {
950     size_t len = PAGE_SIZE;
951 
952     void *mem = mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
953     LOG("__LINE__ = %d, mem = %p", __LINE__, mem);
954     ASSERT_TRUE(mem != MAP_FAILED) << "mem == MAP_FAILED";
955 
956     EXPECT_TRUE(munmap(NULL, len) == -1) << "ERROR: munmap() != -1";
957     EXPECT_TRUE(errno == EINVAL) << "ERROR: errno != EINVAL, errno = " << errno << " EINVAL = " << EINVAL;
958 
959     EXPECT_TRUE(munmap(mem, 0) == -1) << "ERROR: munmap() != -1";
960     EXPECT_TRUE(errno == EINVAL) << "ERROR: errno != EINVAL, errno = " << errno << " EINVAL = " << EINVAL;
961 
962     EXPECT_TRUE(munmap(mem, len) == 0) << "ERROR: munmap() != 0";
963 }
964