From ceda5688b650646248f269a992c06b11148c5759 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 20 Aug 2023 12:38:49 -0700 Subject: [PATCH] linux-user: Fix shmdt MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit If the shm region is not mapped at shmaddr, EINVAL. Do not unmap the region until the syscall succeeds. Use mmap_reserve_or_unmap to preserve reserved_va semantics. Tested-by: Helge Deller Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- linux-user/mmap.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/linux-user/mmap.c b/linux-user/mmap.c index f45b2d307c..44116c014b 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -1102,14 +1102,25 @@ abi_long target_shmdt(abi_ulong shmaddr) /* shmdt pointers are always untagged */ WITH_MMAP_LOCK_GUARD() { - for (int i = 0; i < N_SHM_REGIONS; ++i) { + int i; + + for (i = 0; i < N_SHM_REGIONS; ++i) { if (shm_regions[i].in_use && shm_regions[i].start == shmaddr) { - shm_regions[i].in_use = false; - page_set_flags(shmaddr, shmaddr + shm_regions[i].size - 1, 0); break; } } + if (i == N_SHM_REGIONS) { + return -TARGET_EINVAL; + } + rv = get_errno(shmdt(g2h_untagged(shmaddr))); + if (rv == 0) { + abi_ulong size = shm_regions[i].size; + + shm_regions[i].in_use = false; + page_set_flags(shmaddr, shmaddr + size - 1, 0); + mmap_reserve_or_unmap(shmaddr, size); + } } return rv; } -- 2.39.2