From nobody Wed Oct 22 06:35:01 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1519852292140589.544924134099; Wed, 28 Feb 2018 13:11:32 -0800 (PST) Received: from localhost ([::1]:46938 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1er90c-00014B-Q5 for importer@patchew.org; Wed, 28 Feb 2018 16:11:30 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46264) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1er8vs-0005h5-8N for qemu-devel@nongnu.org; Wed, 28 Feb 2018 16:06:39 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1er8vq-0000Wh-Tc for qemu-devel@nongnu.org; Wed, 28 Feb 2018 16:06:36 -0500 Received: from mail-lf0-x243.google.com ([2a00:1450:4010:c07::243]:36948) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1er8vq-0000Va-I1; Wed, 28 Feb 2018 16:06:34 -0500 Received: by mail-lf0-x243.google.com with SMTP id y19so5627488lfd.4; Wed, 28 Feb 2018 13:06:34 -0800 (PST) Received: from octofox.cadence.com (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id l8sm547134lfb.19.2018.02.28.13.06.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 28 Feb 2018 13:06:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Jx1zurxifg0T4seD37fmT/vF/FOPjzXG0nJrQOskNXo=; b=hQA/t/Y6LW0ZKM1PaDvH4Bux3F0lsNl13AFnd2Cha0YyVrHjy69dlwPQ1/eyHe4K4m 2Z921IYmczoJgrDShXcJKg55lJhP9PFElhhElXpQDMk11BQ7s9U3EmIky5gBsyPENoE4 GdRFMC2P4iFcbQfIz1hiB9iG5clxfiDw2lyDkfBkxu2JmMI2f5DGOrbzI+7K4w6LjpB4 MuQd00IDzv8PQDOqhhYZbedjTy2lsrdsLBuU8J51IYIUeoNXsMlDxJVQW1uzjCTeTVhV m7WFPx7T1CAUcKM9ytI2h+bh9s9aVS58s9IxmyEcawA9KMCJbZHW7H1jRs+yx31W1AAD vX3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Jx1zurxifg0T4seD37fmT/vF/FOPjzXG0nJrQOskNXo=; b=MiFMe3Q3QGXPYIbWlYXsBEGH5WWv7GiKrZoh/zSUvkw0SM/dkcEEws0tjnnxqd2E6k ZjfQLJkY67NkxEs6usEUe4KdUYv2jAoD61dy+DQOXmyHgedx6EmYwvoyFbYghhV905uk I0NSw55VvAPgOhZjTq5aRbst79eBkTA7fn4RuYlppCGYX/FpJVVbxL4I/1km0uOutIED OY6AdDyVcqbr7gZ1kyLp4knOfCORrFN/F2tlNgRtle/WBVK97DaV0EDQUn4jZKHV8lon MrsOarDrWomyfciatYtYI646guujXyCzAuNMtoIgskNAMW5skfaRxVJwa36MQcdGGBQ/ SZVA== X-Gm-Message-State: APf1xPAZmCr67W45hcwsgkBhRuw7vWH77vmHlFHd3mfXe8qWDYkwXc/F mnfNXgTRseEainQZ40CmfbUCEg== X-Google-Smtp-Source: AG47ELvOVK4MQWk51cfJ5MuL53XS3CLFAroGtm5J/dPROkGvg1aWBmyaTArYuE9TxrIgfjKMLb+6fQ== X-Received: by 10.46.122.15 with SMTP id v15mr14962452ljc.141.1519851993077; Wed, 28 Feb 2018 13:06:33 -0800 (PST) From: Max Filippov To: qemu-devel@nongnu.org Date: Wed, 28 Feb 2018 13:06:10 -0800 Message-Id: <20180228210616.2756-6-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180228210616.2756-1-jcmvbkbc@gmail.com> References: <20180228210616.2756-1-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4010:c07::243 Subject: [Qemu-devel] [PATCH 05/11] linux-user: fix mmap/munmap/mprotect/mremap/shmat X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Max Filippov , Riku Voipio , qemu-stable@nongnu.org, Laurent Vivier Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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. Introduce macro 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 --- include/exec/cpu-all.h | 2 +- include/exec/cpu_ldst.h | 12 +++++++----- linux-user/mmap.c | 20 +++++++++++++++----- linux-user/syscall.c | 3 +++ 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 0b141683f095..12bd049997ac 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -160,7 +160,7 @@ extern int have_guest_base; extern unsigned long reserved_va; =20 #define GUEST_ADDR_MAX (reserved_va ? reserved_va : \ - (1ul << TARGET_VIRT_ADDR_SPACE_BITS) -= 1) + (2ul << (TARGET_VIRT_ADDR_SPACE_BITS - 1)) - 1) #else =20 #include "exec/hwaddr.h" diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h index 191f2e962a3c..bbf6988bc725 100644 --- a/include/exec/cpu_ldst.h +++ b/include/exec/cpu_ldst.h @@ -53,14 +53,16 @@ =20 #if HOST_LONG_BITS <=3D TARGET_VIRT_ADDR_SPACE_BITS #define h2g_valid(x) 1 +#define guest_valid(x) 1 #else -#define h2g_valid(x) ({ \ - unsigned long __guest =3D (unsigned long)(x) - guest_base; \ - (__guest < (1ul << TARGET_VIRT_ADDR_SPACE_BITS)) && \ - (!reserved_va || (__guest < reserved_va)); \ -}) +#define h2g_valid(x) guest_valid((unsigned long)(x) - guest_base) +#define guest_valid(x) ((x) <=3D GUEST_ADDR_MAX) #endif =20 +#define guest_range_valid(start, len) \ + ({unsigned long l =3D (len); \ + guest_valid(l) && (start) <=3D GUEST_ADDR_MAX - l; }) + #define h2g_nocheck(x) ({ \ unsigned long __ret =3D (unsigned long)(x) - guest_base; \ (abi_ulong)__ret; \ diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 0fbfd6dff20d..df81f9b803b6 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -80,8 +80,9 @@ int target_mprotect(abi_ulong start, abi_ulong len, int p= rot) return -EINVAL; len =3D TARGET_PAGE_ALIGN(len); end =3D start + len; - if (end < start) - return -EINVAL; + if (!guest_range_valid(start, len)) { + return -ENOMEM; + } prot &=3D PROT_READ | PROT_WRITE | PROT_EXEC; if (len =3D=3D 0) return 0; @@ -481,8 +482,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, in= t prot, * It can fail only on 64-bit host with 32-bit target. * On any other target/host host mmap() handles this error correctly. */ - if ((unsigned long)start + len - 1 > (abi_ulong) -1) { - errno =3D EINVAL; + if (!guest_range_valid(start, len)) { + errno =3D ENOMEM; goto fail; } =20 @@ -622,8 +623,10 @@ int target_munmap(abi_ulong start, abi_ulong len) if (start & ~TARGET_PAGE_MASK) return -EINVAL; len =3D TARGET_PAGE_ALIGN(len); - if (len =3D=3D 0) + if (len =3D=3D 0 || !guest_range_valid(start, len)) { return -EINVAL; + } + mmap_lock(); end =3D start + len; real_start =3D start & qemu_host_page_mask; @@ -678,6 +681,13 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong o= ld_size, int prot; void *host_addr; =20 + if (!guest_range_valid(old_addr, old_size) || + ((flags & MREMAP_FIXED) && + !guest_range_valid(new_addr, new_size))) { + errno =3D ENOMEM; + return -1; + } + mmap_lock(); =20 if (flags & MREMAP_FIXED) { diff --git a/linux-user/syscall.c b/linux-user/syscall.c index e24f43c4a259..79245e73784f 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4900,6 +4900,9 @@ static inline abi_ulong do_shmat(CPUArchState *cpu_en= v, return -TARGET_EINVAL; } } + if (!guest_range_valid(shmaddr, shm_info.shm_segsz)) { + return -TARGET_EINVAL; + } =20 mmap_lock(); =20 --=20 2.11.0