munmap-multi-region-unmapping.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * Copyright (c) 2021, the SerenityOS developers.
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Types.h>
  7. #include <fcntl.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <sys/mman.h>
  11. #include <unistd.h>
  12. int main()
  13. {
  14. {
  15. printf("Testing full unnmap\n");
  16. auto* map1 = mmap(nullptr, 2 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0);
  17. if (map1 == MAP_FAILED) {
  18. perror("mmap 1");
  19. return 1;
  20. }
  21. auto* map2 = mmap((void*)((FlatPtr)map1 + 2 * PAGE_SIZE), 2 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0);
  22. if (map2 == MAP_FAILED) {
  23. perror("mmap 2");
  24. return 1;
  25. }
  26. ((u32*)map1)[0] = 0x41414141;
  27. ((u32*)map1)[PAGE_SIZE / sizeof(u32)] = 0x42424242;
  28. ((u32*)map2)[0] = 0xbeefbeef;
  29. ((u32*)map2)[PAGE_SIZE / sizeof(u32)] = 0xc0dec0de;
  30. if (((u32*)map1)[0] != 0x41414141 || ((u32*)map1)[PAGE_SIZE / sizeof(u32)] != 0x42424242
  31. || ((u32*)map2)[0] != 0xbeefbeef || ((u32*)map2)[PAGE_SIZE / sizeof(u32)] != 0xc0dec0de) {
  32. perror("write");
  33. return 1;
  34. }
  35. int res = munmap(map1, 4 * PAGE_SIZE);
  36. if (res < 0) {
  37. perror("unmap");
  38. return 1;
  39. }
  40. }
  41. {
  42. printf("Testing partial unmapping\n");
  43. auto* map1 = mmap(nullptr, 2 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0);
  44. if (map1 == MAP_FAILED) {
  45. perror("mmap 1");
  46. return 1;
  47. }
  48. auto* map2 = mmap((void*)((FlatPtr)map1 + 2 * PAGE_SIZE), 2 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0);
  49. if (map2 == MAP_FAILED) {
  50. perror("mmap 2");
  51. return 1;
  52. }
  53. ((u32*)map1)[0] = 0x41414141;
  54. ((u32*)map1)[PAGE_SIZE / sizeof(u32)] = 0x42424242;
  55. ((u32*)map2)[0] = 0xbeefbeef;
  56. ((u32*)map2)[PAGE_SIZE / sizeof(u32)] = 0xc0dec0de;
  57. if (((u32*)map1)[0] != 0x41414141 || ((u32*)map1)[PAGE_SIZE / sizeof(u32)] != 0x42424242
  58. || ((u32*)map2)[0] != 0xbeefbeef || ((u32*)map2)[PAGE_SIZE / sizeof(u32)] != 0xc0dec0de) {
  59. perror("write");
  60. return 1;
  61. }
  62. int res = munmap((void*)((FlatPtr)map1 + PAGE_SIZE), 2 * PAGE_SIZE);
  63. if (res < 0) {
  64. perror("unmap");
  65. return 1;
  66. }
  67. auto* map3 = mmap((void*)((FlatPtr)map1 + PAGE_SIZE), PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0);
  68. if (map3 == MAP_FAILED) {
  69. perror("remap 1");
  70. return 1;
  71. }
  72. auto* map4 = mmap(map2, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0);
  73. if (map4 == MAP_FAILED) {
  74. perror("remap 2");
  75. return 1;
  76. }
  77. ((u32*)map3)[0] = 0x13371337;
  78. ((u32*)map4)[0] = 0x1b1b1b1b;
  79. if (((u32*)map1)[0] != 0x41414141 || ((u32*)map2)[PAGE_SIZE / sizeof(u32)] != 0xc0dec0de
  80. || ((u32*)map3)[0] != 0x13371337 || ((u32*)map4)[0] != 0x1b1b1b1b
  81. || ((u32*)map1)[PAGE_SIZE / sizeof(int)] != ((u32*)map3)[0] || ((u32*)map2)[0] != ((u32*)map4)[0]) {
  82. perror("read at old map and write at remap");
  83. return 1;
  84. }
  85. res = munmap(map1, PAGE_SIZE * 4);
  86. if (res < 0) {
  87. perror("cleanup");
  88. return 1;
  89. }
  90. }
  91. printf("PASS\n");
  92. return 0;
  93. }