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