On 03/10/2023 07:41, Chaitanya S Prakash wrote:
Only valid owning capabilities are allowed to manage memory mappings. Passing a capability with it's tag bit cleared will result in failure of the syscall. Tests to verify this behaviour have been added.
Signed-off-by: Chaitanya S Prakash chaitanyas.prakash@arm.com
tools/testing/selftests/arm64/morello/mmap.c | 111 +++++++++++++++++++ 1 file changed, 111 insertions(+)
diff --git a/tools/testing/selftests/arm64/morello/mmap.c b/tools/testing/selftests/arm64/morello/mmap.c index 831b8832bb74..8a4cc40e6095 100644 --- a/tools/testing/selftests/arm64/morello/mmap.c +++ b/tools/testing/selftests/arm64/morello/mmap.c @@ -138,6 +138,116 @@ TEST(test_map_growsdown) VERIFY_ERRNO((unsigned long)ptr, (unsigned long)-EOPNOTSUPP); } +/* test to validate parameters passed to address space management syscalls */ +TEST(test_validity_tag_check) +{
- void *ptr, *new_ptr;
- int retval;
- int prot = PROT_READ | PROT_WRITE;
- int flags = MAP_PRIVATE | MAP_ANONYMOUS;
- unsigned char vec[MMAP_SIZE / pagesize];
- /* passing invalid capability to mmap() */
- ptr = mmap(NULL, MMAP_SIZE, prot, flags, -1, 0);
- ASSERT_FALSE(IS_ERR_VALUE(ptr));
- new_ptr = mmap(cheri_tag_clear(ptr), MMAP_SIZE_REDUCED, prot,
flags | MAP_FIXED, -1, 0);
- VERIFY_ERRNO((unsigned long)new_ptr, (unsigned long)-EINVAL);
- retval = munmap(ptr, MMAP_SIZE);
- ASSERT_EQ(retval, 0);
- /* passing invalid capability to munmap() */
- ptr = mmap(NULL, MMAP_SIZE, prot, flags, -1, 0);
- ASSERT_FALSE(IS_ERR_VALUE(ptr));
- EXPECT_EQ(0, probe_mem_range(ptr, MMAP_SIZE,
PROBE_MODE_TOUCH | PROBE_MODE_VERIFY));
- retval = munmap(cheri_tag_clear(ptr), MMAP_SIZE);
- VERIFY_ERRNO(retval, -EINVAL);
- retval = munmap(ptr, MMAP_SIZE);
- ASSERT_EQ(retval, 0);
- /* passing invalid capability to mremap() */
- ptr = mmap(NULL, MMAP_SIZE_REDUCED, prot, flags, -1, 0);
- ASSERT_FALSE(IS_ERR_VALUE(ptr));
- new_ptr = mremap(cheri_tag_clear(ptr), MMAP_SIZE_REDUCED, MMAP_SIZE,
MREMAP_MAYMOVE, 0);
- VERIFY_ERRNO((unsigned long)new_ptr, (unsigned long)-EINVAL);
From here on we could just call the remaining syscalls in a row, without creating and destroying a mapping every time, since every syscall is supposed to fail (and therefore have no effect). We could do something similar in patch 7 too.
Kevin
- retval = munmap(ptr, MMAP_SIZE_REDUCED);
- ASSERT_EQ(retval, 0);
- /* passing invalid capability to mprotect() */
- ptr = mmap(NULL, MMAP_SIZE, PROT_MAX(prot) | PROT_READ, flags, -1, 0);
- ASSERT_FALSE(IS_ERR_VALUE(ptr));
- retval = mprotect(cheri_tag_clear(ptr), MMAP_SIZE, PROT_WRITE);
- VERIFY_ERRNO(retval, -EINVAL);
- retval = munmap(ptr, MMAP_SIZE);
- ASSERT_EQ(retval, 0);
- /* passing invalid capability to madvise() */
- ptr = mmap(NULL, MMAP_SIZE, prot, flags, -1, 0);
- ASSERT_FALSE(IS_ERR_VALUE(ptr));
- retval = madvise(cheri_tag_clear(ptr), MMAP_SIZE, MADV_WILLNEED);
- VERIFY_ERRNO(retval, -EINVAL);
- retval = munmap(ptr, MMAP_SIZE);
- ASSERT_EQ(retval, 0);
- /* passing invalid capability to mincore() */
- ptr = mmap(NULL, MMAP_SIZE, prot, flags, -1, 0);
- ASSERT_FALSE(IS_ERR_VALUE(ptr));
- retval = mincore(cheri_tag_clear(ptr), MMAP_SIZE, vec);
- VERIFY_ERRNO(retval, -EINVAL);
- retval = munmap(ptr, MMAP_SIZE);
- ASSERT_EQ(retval, 0);
- /* passing invalid capability to mlock() */
- ptr = mmap(NULL, MMAP_SIZE, prot, flags, -1, 0);
- ASSERT_FALSE(IS_ERR_VALUE(ptr));
- retval = mlock(cheri_tag_clear(ptr), MMAP_SIZE);
- VERIFY_ERRNO(retval, -EINVAL);
- retval = munmap(ptr, MMAP_SIZE);
- ASSERT_EQ(retval, 0);
- /* passing invalid capability to mlock2() */
- ptr = mmap(NULL, MMAP_SIZE, prot, flags, -1, 0);
- ASSERT_FALSE(IS_ERR_VALUE(ptr));
- retval = mlock2(cheri_tag_clear(ptr), MMAP_SIZE, MLOCK_ONFAULT);
- VERIFY_ERRNO(retval, -EINVAL);
- retval = munmap(ptr, MMAP_SIZE);
- ASSERT_EQ(retval, 0);
- /* passing invalid capability to munlock() */
- ptr = mmap(NULL, MMAP_SIZE, prot, flags, -1, 0);
- ASSERT_FALSE(IS_ERR_VALUE(ptr));
- EXPECT_EQ(0, mlock(ptr, MMAP_SIZE_REDUCED));
- EXPECT_EQ(0, probe_mem_range(ptr, MMAP_SIZE_REDUCED,
PROBE_MODE_TOUCH | PROBE_MODE_VERIFY));
- retval = munlock(cheri_tag_clear(ptr), MMAP_SIZE_REDUCED);
- VERIFY_ERRNO(retval, -EINVAL);
- retval = munlock(ptr, MMAP_SIZE_REDUCED);
- ASSERT_EQ(retval, 0);
- retval = munmap(ptr, MMAP_SIZE);
- ASSERT_EQ(retval, 0);
- /* passing invalid capability to msync() */
- ptr = mmap(NULL, MMAP_SIZE, prot, flags, -1, 0);
- ASSERT_FALSE(IS_ERR_VALUE(ptr));
- retval = msync(cheri_tag_clear(ptr), MMAP_SIZE, MS_SYNC);
- VERIFY_ERRNO(retval, -EINVAL);
- retval = munmap(ptr, MMAP_SIZE);
- ASSERT_EQ(retval, 0);
+}
int main(int argc, char **argv, char **envp, struct morello_auxv *auxv) { reg_data.argc = argc; @@ -150,5 +260,6 @@ int main(int argc, char **argv, char **envp, struct morello_auxv *auxv) test_syscall_mmap(); test_syscall_mmap2(); test_map_growsdown();
- test_validity_tag_check(); return 0;
}