From ebf9a3630c911d0cfc9c20f7cafe9ba4f88cf583 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Wed, 7 Mar 2018 13:50:10 -0800 Subject: linux-user: fix mmap/munmap/mprotect/mremap/shmat In linux-user QEMU that runs for a target with TARGET_ABI_BITS bigger than L1_MAP_ADDR_SPACE_BITS an assertion in page_set_flags fires when mmap, munmap, mprotect, mremap or shmat is called for an address outside the guest address space. mmap and mprotect should return ENOMEM in such case. Change definition of GUEST_ADDR_MAX to always be the last valid guest address. Account for this change in open_self_maps. Add macro guest_addr_valid that verifies if the guest address is valid. Add function guest_range_valid that verifies if address range is within guest address space and does not wrap around. Use that macro in mmap/munmap/mprotect/mremap/shmat for error checking. Cc: qemu-stable@nongnu.org Cc: Riku Voipio Cc: Laurent Vivier Signed-off-by: Max Filippov Reviewed-by: Laurent Vivier Message-Id: <20180307215010.30706-1-jcmvbkbc@gmail.com> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'linux-user/syscall.c') diff --git a/linux-user/syscall.c b/linux-user/syscall.c index e1c3127bdc..8cbe4499b2 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4900,6 +4900,9 @@ static inline abi_ulong do_shmat(CPUArchState *cpu_env, return -TARGET_EINVAL; } } + if (!guest_range_valid(shmaddr, shm_info.shm_segsz)) { + return -TARGET_EINVAL; + } mmap_lock(); @@ -7468,7 +7471,7 @@ static int open_self_maps(void *cpu_env, int fd) } if (h2g_valid(min)) { int flags = page_get_flags(h2g(min)); - max = h2g_valid(max - 1) ? max : (uintptr_t)g2h(GUEST_ADDR_MAX); + max = h2g_valid(max - 1) ? max : (uintptr_t)g2h(GUEST_ADDR_MAX) + 1; if (page_check_range(h2g(min), max - min, flags) == -1) { continue; } -- cgit 1.4.1