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 31using namespace testing::ext; 32 33#define MMAP_TESTFILE "/storage/testMmap.txt" 34 35class 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 */ 43HWTEST_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 */ 83HWTEST_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 */ 117HWTEST_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 */ 146HWTEST_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 */ 177HWTEST_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 */ 225HWTEST_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 */ 274HWTEST_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 */ 315HWTEST_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 */ 361HWTEST_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 */ 407HWTEST_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 */ 448HWTEST_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 */ 491HWTEST_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 */ 538HWTEST_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 */ 585HWTEST_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 */ 629HWTEST_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 */ 700HWTEST_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 */ 762HWTEST_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 */ 803HWTEST_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 */ 832HWTEST_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 */ 908HWTEST_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 */ 948HWTEST_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