summaryrefslogtreecommitdiff
path: root/linux-user/mmap.c
diff options
context:
space:
mode:
authorTobias Koch <tobias.koch@nonterra.com>2020-10-28 22:38:33 +0100
committerLaurent Vivier <laurent@vivier.eu>2020-12-17 10:34:27 +0100
commit56d190848b9b8ecb8213835b0d2d05b243bcb5b8 (patch)
tree91036daf57137b64b149c46f79a791e427dc6905 /linux-user/mmap.c
parentaf3f37319cb1e1ca0c42842ecdbd1bcfc64a4b6f (diff)
downloadqemu-56d190848b9b8ecb8213835b0d2d05b243bcb5b8.zip
linux-user/mmap.c: check range of mremap result in target address space
If mremap succeeds, an additional check is performed to ensure that the new address range fits into the target address space. This check was previously perfomed in host address space, with the upper bound fixed to abi_ulong. This patch replaces the static check with a call to `guest_range_valid`, performing the range check against the actual size of the target address space. It also moves the corresponding block to prevent it from being called incorrectly when the mapping itself fails. Signed-off-by: Tobias Koch <tobias.koch@nonterra.com> Message-Id: <20201028213833.26592-1-tobias.koch@nonterra.com> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Diffstat (limited to 'linux-user/mmap.c')
-rw-r--r--linux-user/mmap.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 00c05e6a0f..810653c503 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -767,20 +767,23 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
}
if (prot == 0) {
host_addr = mremap(g2h(old_addr), old_size, new_size, flags);
- if (host_addr != MAP_FAILED && reserved_va && old_size > new_size) {
- mmap_reserve(old_addr + old_size, old_size - new_size);
+
+ if (host_addr != MAP_FAILED) {
+ /* Check if address fits target address space */
+ if (!guest_range_valid(h2g(host_addr), new_size)) {
+ /* Revert mremap() changes */
+ host_addr = mremap(g2h(old_addr), new_size, old_size,
+ flags);
+ errno = ENOMEM;
+ host_addr = MAP_FAILED;
+ } else if (reserved_va && old_size > new_size) {
+ mmap_reserve(old_addr + old_size, old_size - new_size);
+ }
}
} else {
errno = ENOMEM;
host_addr = MAP_FAILED;
}
- /* Check if address fits target address space */
- if ((unsigned long)host_addr + new_size > (abi_ulong)-1) {
- /* Revert mremap() changes */
- host_addr = mremap(g2h(old_addr), new_size, old_size, flags);
- errno = ENOMEM;
- host_addr = MAP_FAILED;
- }
}
if (host_addr == MAP_FAILED) {