On Sat, Aug 17, 2024 at 01:18:34AM GMT, Pedro Falcato wrote: > Add more mseal traversal tests across VMAs, where we could possibly > screw up sealing checks. These test more across-vma traversal for > mprotect, munmap and madvise. Particularly, we test for the case where a > regular VMA is followed by a sealed VMA. > > Signed-off-by: Pedro Falcato <pedro.falcato@xxxxxxxxx> Other than the comment, LGTM. Thanks for this series! Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@xxxxxxxxxx> > --- > tools/testing/selftests/mm/mseal_test.c | 111 +++++++++++++++++++++++++++++++- > 1 file changed, 110 insertions(+), 1 deletion(-) > > diff --git a/tools/testing/selftests/mm/mseal_test.c b/tools/testing/selftests/mm/mseal_test.c > index 259bef4945e9..0d4d40fb0f88 100644 > --- a/tools/testing/selftests/mm/mseal_test.c > +++ b/tools/testing/selftests/mm/mseal_test.c > @@ -766,6 +766,42 @@ static void test_seal_mprotect_partial_mprotect(bool seal) > REPORT_TEST_PASS(); > } > > +static void test_seal_mprotect_partial_mprotect_tail(bool seal) > +{ > + void *ptr; > + unsigned long page_size = getpagesize(); > + unsigned long size = 2 * page_size; > + int ret; > + int prot; > + > + /* > + * Check if a partial mseal (that results in two vmas) works correctly. > + * It might mprotect the first, but it'll never touch the second (msealed) vma. > + */ > + > + setup_single_address(size, &ptr); > + FAIL_TEST_IF_FALSE(ptr != (void *)-1); > + > + if (seal) { > + ret = sys_mseal(ptr + page_size, size); > + FAIL_TEST_IF_FALSE(!ret); > + } > + > + ret = sys_mprotect(ptr, size, PROT_EXEC); > + if (seal) > + FAIL_TEST_IF_FALSE(ret < 0); > + else > + FAIL_TEST_IF_FALSE(!ret); > + > + if (seal) { > + FAIL_TEST_IF_FALSE(get_vma_size(ptr + page_size, &prot) > 0); > + FAIL_TEST_IF_FALSE(prot == 0x4); > + } > + > + REPORT_TEST_PASS(); > +} > + > + > static void test_seal_mprotect_two_vma_with_gap(bool seal) > { > void *ptr; > @@ -983,6 +1019,41 @@ static void test_seal_munmap_vma_with_gap(bool seal) > REPORT_TEST_PASS(); > } > > +static void test_seal_munmap_partial_across_vmas(bool seal) > +{ > + void *ptr; > + unsigned long page_size = getpagesize(); > + unsigned long size = 2 * page_size; > + int ret; > + int prot; > + > + /* > + * Check if a partial mseal (that results in two vmas) works correctly. > + * It might unmap the first, but it'll never unmap the second (msealed) vma. > + */ > + > + setup_single_address(size, &ptr); > + FAIL_TEST_IF_FALSE(ptr != (void *)-1); > + > + if (seal) { > + ret = sys_mseal(ptr + page_size, size); > + FAIL_TEST_IF_FALSE(!ret); > + } > + > + ret = sys_munmap(ptr, size); > + if (seal) > + FAIL_TEST_IF_FALSE(ret < 0); > + else > + FAIL_TEST_IF_FALSE(!ret); > + > + if (seal) { > + FAIL_TEST_IF_FALSE(get_vma_size(ptr + page_size, &prot) > 0); > + FAIL_TEST_IF_FALSE(prot == 0x4); > + } > + > + REPORT_TEST_PASS(); > +} > + > static void test_munmap_start_freed(bool seal) > { > void *ptr; > @@ -1735,6 +1806,37 @@ static void test_seal_discard_ro_anon(bool seal) > REPORT_TEST_PASS(); > } > > +static void test_seal_discard_across_vmas(bool seal) > +{ > + void *ptr; > + unsigned long page_size = getpagesize(); > + unsigned long size = 2 * page_size; > + int ret; > + > + setup_single_address(size, &ptr); > + FAIL_TEST_IF_FALSE(ptr != (void *)-1); > + > + if (seal) { > + ret = seal_single_address(ptr + page_size, page_size); > + FAIL_TEST_IF_FALSE(!ret); > + } > + > + ret = sys_madvise(ptr, size, MADV_DONTNEED); > + if (seal) > + FAIL_TEST_IF_FALSE(ret < 0); > + else > + FAIL_TEST_IF_FALSE(!ret); > + > + ret = sys_munmap(ptr, size); > + if (seal) > + FAIL_TEST_IF_FALSE(ret < 0); > + else > + FAIL_TEST_IF_FALSE(!ret); > + > + REPORT_TEST_PASS(); > +} > + > + > static void test_seal_madvise_nodiscard(bool seal) > { > void *ptr; > @@ -1779,7 +1881,7 @@ int main(int argc, char **argv) > if (!pkey_supported()) > ksft_print_msg("PKEY not supported\n"); > > - ksft_set_plan(82); > + ksft_set_plan(88); > > test_seal_addseal(); > test_seal_unmapped_start(); > @@ -1825,12 +1927,17 @@ int main(int argc, char **argv) > test_seal_mprotect_split(false); > test_seal_mprotect_split(true); > > + test_seal_mprotect_partial_mprotect_tail(false); > + test_seal_mprotect_partial_mprotect_tail(true); > + > test_seal_munmap(false); > test_seal_munmap(true); > test_seal_munmap_two_vma(false); > test_seal_munmap_two_vma(true); > test_seal_munmap_vma_with_gap(false); > test_seal_munmap_vma_with_gap(true); > + test_seal_munmap_partial_across_vmas(false); > + test_seal_munmap_partial_across_vmas(true); > > test_munmap_start_freed(false); > test_munmap_start_freed(true); > @@ -1862,6 +1969,8 @@ int main(int argc, char **argv) > test_seal_madvise_nodiscard(true); > test_seal_discard_ro_anon(false); > test_seal_discard_ro_anon(true); > + test_seal_discard_across_vmas(false); > + test_seal_discard_across_vmas(true); > test_seal_discard_ro_anon_on_rw(false); > test_seal_discard_ro_anon_on_rw(true); > test_seal_discard_ro_anon_on_shared(false); > > -- > 2.46.0 >