@@ -1969,6 +1969,79 @@ static void test_madvise_filebacked_was_writable(bool seal)
REPORT_TEST_PASS();
}
+static void test_munmap_free_multiple_ranges_with_split(bool seal)
+{
+ void *ptr;
+ unsigned long page_size = getpagesize();
+ unsigned long size = 12 * page_size;
+ int ret;
+ int prot;
+
+ setup_single_address(size, &ptr);
+ FAIL_TEST_IF_FALSE(ptr != (void *)-1);
+
+ /* seal the middle 4 page */
+ if (seal) {
+ ret = sys_mseal(ptr + 4 * page_size, 4 * page_size);
+ FAIL_TEST_IF_FALSE(!ret);
+
+ size = get_vma_size(ptr, &prot);
+ FAIL_TEST_IF_FALSE(size == 4 * page_size);
+ FAIL_TEST_IF_FALSE(prot == 4);
+
+ size = get_vma_size(ptr + 4 * page_size, &prot);
+ FAIL_TEST_IF_FALSE(size == 4 * page_size);
+ FAIL_TEST_IF_FALSE(prot == 4);
+
+ size = get_vma_size(ptr + 8 * page_size, &prot);
+ FAIL_TEST_IF_FALSE(size == 4 * page_size);
+ FAIL_TEST_IF_FALSE(prot == 4);
+ }
+
+ /* munmap 4 pages from the third page */
+ ret = sys_munmap(ptr + 2 * page_size, 4 * page_size);
+ if (seal) {
+ FAIL_TEST_IF_FALSE(ret);
+ FAIL_TEST_IF_FALSE(errno == EPERM);
+
+ size = get_vma_size(ptr, &prot);
+ FAIL_TEST_IF_FALSE(size == 4 * page_size);
+ FAIL_TEST_IF_FALSE(prot == 4);
+
+ size = get_vma_size(ptr + 4 * page_size, &prot);
+ FAIL_TEST_IF_FALSE(size == 4 * page_size);
+ FAIL_TEST_IF_FALSE(prot == 4);
+
+ size = get_vma_size(ptr + 8 * page_size, &prot);
+ FAIL_TEST_IF_FALSE(size == 4 * page_size);
+ FAIL_TEST_IF_FALSE(prot == 4);
+ } else
+ FAIL_TEST_IF_FALSE(!ret);
+
+ /* munmap 4 pages from the sealed page */
+ ret = sys_munmap(ptr + 6 * page_size, 4 * page_size);
+ if (seal) {
+ FAIL_TEST_IF_FALSE(ret);
+ FAIL_TEST_IF_FALSE(errno == EPERM);
+
+ size = get_vma_size(ptr + 4 * page_size, &prot);
+ FAIL_TEST_IF_FALSE(size == 4 * page_size);
+ FAIL_TEST_IF_FALSE(prot == 4);
+
+ size = get_vma_size(ptr + 4 * page_size, &prot);
+ FAIL_TEST_IF_FALSE(size == 4 * page_size);
+ FAIL_TEST_IF_FALSE(prot == 4);
+
+ size = get_vma_size(ptr + 8 * page_size, &prot);
+ FAIL_TEST_IF_FALSE(size == 4 * page_size);
+ FAIL_TEST_IF_FALSE(prot == 4);
+ } else
+ FAIL_TEST_IF_FALSE(!ret);
+
+ REPORT_TEST_PASS();
+}
+
+
int main(int argc, char **argv)
{
bool test_seal = seal_support();
@@ -2099,5 +2172,8 @@ int main(int argc, char **argv)
test_madvise_filebacked_was_writable(false);
test_madvise_filebacked_was_writable(true);
+ test_munmap_free_multiple_ranges_with_split(false);
+ test_munmap_free_multiple_ranges_with_split(true);
+
ksft_finished();
}
From: Jeff Xu <jeffxu@google.com> It appears there is a regression on the latest mm, when munmap sealed memory, it can cause unexpected VMA split. E.g. repro use this test. --- tools/testing/selftests/mm/mseal_test.c | 76 +++++++++++++++++++++++++ 1 file changed, 76 insertions(+)