From da39a3ee5e6b4b0d3255bfef95601890afd80709 Mon Sep 17 00:00:00 2001
From: Jürgen Buchmüller <pullmoll@t-online.de>
Subject: [PATCH] linux-user: Return errno=EFAULT on invalid address to mremap

Also speed up the loop when checking for increasing the mappings size to go
in steps of TARGET_PAGE_SIZE and OR-in a check for the very last byte of
the range.

Ref: <https://www.openwall.com/lists/musl/2017/06/21/2>

Upstream-Status: Pending
[ismael@iodev.co.uk: Normalized patch format]
---
 linux-user/mmap.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git linux-user/mmap.c linux-user/mmap.c
index 7e3b245..1e8d0f1 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -752,7 +752,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
          !guest_range_valid_untagged(new_addr, new_size)) ||
         ((flags & MREMAP_MAYMOVE) == 0 &&
          !guest_range_valid_untagged(old_addr, new_size))) {
-        errno = ENOMEM;
+        errno = EFAULT;
         return -1;
     }
 
@@ -789,9 +789,10 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
             abi_ulong addr;
             for (addr = old_addr + old_size;
                  addr < old_addr + new_size;
-                 addr++) {
+                 addr += TARGET_PAGE_SIZE) {
                 prot |= page_get_flags(addr);
             }
+            prot |= page_get_flags(old_addr + new_size - 1);
         }
         if (prot == 0) {
             host_addr = mremap(g2h_untagged(old_addr),
@@ -810,7 +811,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
                 }
             }
         } else {
-            errno = ENOMEM;
+            errno = EFAULT;
             host_addr = MAP_FAILED;
         }
     }
