qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] linux-user: mremap fails with EFAULT if address range overlaps with stack guard
@ 2020-03-05 21:05 Tobias Koch
  2020-05-07 14:35 ` Laurent Vivier
  0 siblings, 1 reply; 6+ messages in thread
From: Tobias Koch @ 2020-03-05 21:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: riku.voipio

If the address range starting at old_address overlaps with the stack guard it
is invalid and mremap must fail with EFAULT. The musl c library relies on this
behavior to detect the stack size, which it does by doing consecutive mremaps
until it hits the stack guard. Without this patch, software (such as the Ruby
interpreter) that calls pthread_getattr_np under musl will crash on 32 bit
targets emulated on a 64 bit host.

Signed-off-by: Tobias Koch <tobias.koch@nonterra.com>
---
 linux-user/mmap.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 8685f02e7e..62cddbd072 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -651,6 +651,12 @@ int target_munmap(abi_ulong start, abi_ulong len)
     return ret;
 }
 
+#ifdef TARGET_HPPA
+#define STACK_GROWS_DOWN 0
+#else
+#define STACK_GROWS_DOWN 1
+#endif
+
 abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
                        abi_ulong new_size, unsigned long flags,
                        abi_ulong new_addr)
@@ -665,6 +671,26 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
         return -1;
     }
 
+    /* Check that we're not overlapping with the stack guard. */
+    if (reserved_va) {
+        abi_ulong guard_size, guard_start;
+
+        guard_size = TARGET_PAGE_SIZE < qemu_real_host_page_size ?
+            qemu_real_host_page_size : TARGET_PAGE_SIZE;
+
+        if (STACK_GROWS_DOWN) {
+            guard_start = reserved_va - guest_stack_size - guard_size;
+        } else {
+            guard_start = reserved_va - guard_size;
+        }
+
+        if (guard_start < old_addr + old_size &&
+             old_addr < guard_start + guard_size) {
+            errno = EFAULT;
+            return -1;
+        }
+    }
+
     mmap_lock();
 
     if (flags & MREMAP_FIXED) {
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-07-04 15:05 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-03-05 21:05 [PATCH] linux-user: mremap fails with EFAULT if address range overlaps with stack guard Tobias Koch
2020-05-07 14:35 ` Laurent Vivier
2020-06-15  7:17   ` Tobias Koch
2020-06-15 20:28     ` Tobias Koch
2020-06-15 21:10       ` Tobias Koch
2020-07-04 14:44         ` Tobias Koch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).