On 17-07-2023 06:11, Chaitanya S Prakash wrote:
The length of the initial mapping using an mmap() call has the ability to be reduced in a subsequent mmap() call without first being unmapped. Whereas, trying to increase the length of the initial mapping would result in failure as the capability is not permitted to access a range that it does not own.
Address space management syscalls that manipulate a given mapping are restricted to the range owned by the capability. Any attempt to modify or access memory beyond this range will result in failure of syscall.
Signed-off-by: Chaitanya S Prakash chaitanyas.prakash@arm.com
tools/testing/selftests/arm64/morello/mmap.c | 132 +++++++++++++++++++ 1 file changed, 132 insertions(+)
diff --git a/tools/testing/selftests/arm64/morello/mmap.c b/tools/testing/selftests/arm64/morello/mmap.c index 184dcf4ddc92..4a2a552d47dc 100644 --- a/tools/testing/selftests/arm64/morello/mmap.c +++ b/tools/testing/selftests/arm64/morello/mmap.c @@ -198,6 +198,132 @@ static inline void purecap_param_check(void) ASSERT_EQ(retval, 0); } +/* test to verify address space management syscall behaviour when capability
- range is modified */
Block comments use a trailing */ on a separate line. You have a few other instances in the following patches.
+static inline void purecap_range_check(void) +{
- void *addr, *ret;
- int retval;
- int prot = PROT_READ | PROT_WRITE;
- int flags = MAP_PRIVATE | MAP_ANONYMOUS;
- unsigned char vec[MMAP_SIZE / PAGE_SIZE];
- /* mapping a smaller range at prev mmap addr in a subsequent mmap()
* call without first unmapping */
- addr = mmap(NULL, MMAP_SIZE, prot, flags, -1, 0);
- ASSERT_GT((unsigned long)addr, 0);
- ret = mmap(addr, MMAP_SIZE_REDUCED, prot, flags | MAP_FIXED, -1, 0);
- ASSERT_GT((unsigned long)ret, 0);
- EXPECT_EQ(0, probe_mem_range(addr, MMAP_SIZE_REDUCED,
PROBE_MODE_TOUCH | PROBE_MODE_VERIFY));
- retval = munmap(addr, MMAP_SIZE_REDUCED);
You probably want to munmap the whole MMAP_SIZE here. Otherwise there's a memory leak.
Tudor
- ASSERT_EQ(retval, 0);
- /* mapping a larger range at prev mmap addr in a subsequent mmap()
* call without first unmapping */
- addr = mmap(NULL, MMAP_SIZE, prot, flags, -1, 0);
- ASSERT_GT((unsigned long)addr, 0);
- ret = mmap(addr, 2 * MMAP_SIZE, prot, flags | MAP_FIXED, -1, 0);
- ASSERT_EQ((unsigned long)ret, (unsigned long)-EINVAL);
- retval = munmap(addr, MMAP_SIZE);
- ASSERT_EQ(retval, 0);
- /* positive madvise() range test */
- addr = mmap(NULL, MMAP_SIZE, prot, flags, -1, 0);
- ASSERT_GT((unsigned long)addr, 0);
- retval = madvise(addr, MMAP_SIZE, MADV_WILLNEED);
- ASSERT_NE(retval, -EINVAL);
- EXPECT_EQ(0, probe_mem_range(addr, MMAP_SIZE,
PROBE_MODE_TOUCH | PROBE_MODE_VERIFY));
- retval = munmap(addr, MMAP_SIZE);
- ASSERT_EQ(retval, 0);
- /* negative madvise() range test */
- addr = mmap(NULL, MMAP_SIZE_REDUCED, prot, flags, -1, 0);
- ASSERT_GT((unsigned long)addr, 0);
- retval = madvise(addr, MMAP_SIZE, MADV_NORMAL);
- ASSERT_EQ(retval, -EINVAL);
- retval = munmap(addr, MMAP_SIZE_REDUCED);
- ASSERT_EQ(retval, 0);
- /* positive mincore() range test */
- addr = mmap(NULL, MMAP_SIZE, prot, flags, -1, 0);
- ASSERT_GT((unsigned long)addr, 0);
- retval = mincore(addr, MMAP_SIZE, vec);
- ASSERT_EQ(retval, 0);
- EXPECT_EQ(0, probe_mem_range(addr, MMAP_SIZE,
PROBE_MODE_TOUCH | PROBE_MODE_VERIFY));
- retval = munmap(addr, MMAP_SIZE);
- ASSERT_EQ(retval, 0);
- /* negative mincore() range test */
- addr = mmap(NULL, MMAP_SIZE_REDUCED, prot, flags, -1, 0);
- ASSERT_GT((unsigned long)addr, 0);
- retval = mincore(addr, MMAP_SIZE, vec);
- ASSERT_EQ(retval, -EINVAL);
- retval = munmap(addr, MMAP_SIZE_REDUCED);
- ASSERT_EQ(retval, 0);
- /* positive mlock() range test */
- addr = mmap(NULL, MMAP_SIZE, prot, flags, -1, 0);
- ASSERT_GT((unsigned long)addr, 0);
- retval = mlock(addr, MMAP_SIZE);
- EXPECT_EQ(0, probe_mem_range(addr, MMAP_SIZE,
PROBE_MODE_TOUCH | PROBE_MODE_VERIFY));
- retval = munlock(addr, MMAP_SIZE);
- ASSERT_EQ(retval, 0);
- retval = munmap(addr, MMAP_SIZE);
- ASSERT_EQ(retval, 0);
- /* negative mlock() range test */
- addr = mmap(NULL, MMAP_SIZE_REDUCED, prot, flags, -1, 0);
- ASSERT_GT((unsigned long)addr, 0);
- retval = mlock(addr, MMAP_SIZE);
- ASSERT_EQ(retval, -EINVAL);
- retval = munmap(addr, MMAP_SIZE_REDUCED);
- ASSERT_EQ(retval, 0);
- /* negative munlock() range test */
- addr = mmap(NULL, MMAP_SIZE_REDUCED, prot, flags, -1, 0);
- ASSERT_GT((unsigned long)addr, 0);
- EXPECT_EQ(0, mlock2(addr, MMAP_SIZE_REDUCED, MLOCK_ONFAULT));
- EXPECT_EQ(0, probe_mem_range(addr, MMAP_SIZE_REDUCED,
PROBE_MODE_TOUCH | PROBE_MODE_VERIFY));
- retval = munlock(addr, MMAP_SIZE);
- ASSERT_EQ(retval, -EINVAL);
- retval = munmap(addr, MMAP_SIZE_REDUCED);
- ASSERT_EQ(retval, 0);
- /* positive msync() range test */
- addr = mmap(NULL, MMAP_SIZE, prot, flags, -1, 0);
- ASSERT_GT((unsigned long)addr, 0);
- retval = msync(addr, MMAP_SIZE, MS_SYNC);
- ASSERT_EQ(retval, 0);
- EXPECT_EQ(0, probe_mem_range(addr, MMAP_SIZE,
PROBE_MODE_TOUCH | PROBE_MODE_VERIFY));
- retval = munmap(addr, MMAP_SIZE);
- ASSERT_EQ(retval, 0);
- /* negative msync() range test */
- addr = mmap(NULL, MMAP_SIZE_REDUCED, prot, flags, -1, 0);
- ASSERT_GT((unsigned long)addr, 0);
- retval = msync(addr, MMAP_SIZE, MS_SYNC);
- ASSERT_EQ(retval, -EINVAL);
- retval = munmap(addr, MMAP_SIZE_REDUCED);
- ASSERT_EQ(retval, 0);
+}
- TEST(test_syscall_mmap) { syscall_mmap();
@@ -218,11 +344,17 @@ TEST(test_purecap_param_check) purecap_param_check(); } +TEST(test_purecap_range_check) +{
- purecap_range_check();
+}
- int main(void) { test_syscall_mmap(); test_syscall_mmap2(); test_purecap_map_growsdown(); test_purecap_param_check();
- test_purecap_range_check(); return 0; }