From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3C2A7C34047 for ; Wed, 19 Feb 2020 12:32:05 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 082D924656 for ; Wed, 19 Feb 2020 12:32:04 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 082D924656 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 5F5B26B0003; Wed, 19 Feb 2020 07:32:04 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 5A6EC6B0006; Wed, 19 Feb 2020 07:32:04 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 4BBC16B000A; Wed, 19 Feb 2020 07:32:04 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0185.hostedemail.com [216.40.44.185]) by kanga.kvack.org (Postfix) with ESMTP id 30BA76B0003 for ; Wed, 19 Feb 2020 07:32:04 -0500 (EST) Received: from smtpin12.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with ESMTP id C187D18DD for ; Wed, 19 Feb 2020 12:32:03 +0000 (UTC) X-FDA: 76506813726.12.point39_4c25631ecf555 X-HE-Tag: point39_4c25631ecf555 X-Filterd-Recvd-Size: 5287 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by imf13.hostedemail.com (Postfix) with ESMTP for ; Wed, 19 Feb 2020 12:32:03 +0000 (UTC) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 76CD831B; Wed, 19 Feb 2020 04:32:02 -0800 (PST) Received: from arrakis.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.121.207.14]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 269123F6CF; Wed, 19 Feb 2020 04:32:01 -0800 (PST) From: Catalin Marinas To: Will Deacon , linux-mm@kvack.org Cc: linux-arm-kernel@lists.infradead.org, Szabolcs Nagy , Linus Torvalds , Andrew Morton , Florian Weimer , Victor Stinner , Andrey Konovalov Subject: [PATCH v2] mm: Avoid creating virtual address aliases in brk()/mmap()/mremap() Date: Wed, 19 Feb 2020 12:31:56 +0000 Message-Id: <20200219123156.86952-1-catalin.marinas@arm.com> X-Mailer: git-send-email 2.25.0 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Currently the arm64 kernel ignores the top address byte passed to brk(), mmap() and mremap(). When the user is not aware of the 56-bit address limit or relies on the kernel to return an error, untagging such pointers has the potential to create address aliases in user-space. Passing a tagged address to munmap(), madvise() is permitted since the tagged pointer is expected to be inside an existing mapping. The current behaviour breaks the existing glibc malloc() implementation which relies on brk() with an address beyond 56-bit to be rejected by the kernel. Remove untagging in the above functions by partially reverting commit ce18d171cb73 ("mm: untag user pointers in mmap/munmap/mremap/brk"). In addition, update the arm64 tagged-address-abi.rst document accordingly. Link: https://bugzilla.redhat.com/1797052 Fixes: ce18d171cb73 ("mm: untag user pointers in mmap/munmap/mremap/brk") Cc: # 5.4.x- Cc: Andrew Morton Cc: Florian Weimer Reported-by: Victor Stinner Acked-by: Will Deacon Acked-by: Andrey Konovalov Signed-off-by: Catalin Marinas --- Changes in v2: - Added note to tagged-address-abi.rst that this behaviour changed in v5.= 6 and some older kernel may still have the old behaviour. - Updated the commit log to make it clearer we broke the user ABI, also a= dding link to the Red Hat bugzilla entry. v1 available here: http://lkml.kernel.org/r/20200218122310.72710-1-catalin.marinas@arm.com Documentation/arm64/tagged-address-abi.rst | 11 +++++++++-- mm/mmap.c | 4 ---- mm/mremap.c | 1 - 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Documentation/arm64/tagged-address-abi.rst b/Documentation/a= rm64/tagged-address-abi.rst index d4a85d535bf9..f6289116893c 100644 --- a/Documentation/arm64/tagged-address-abi.rst +++ b/Documentation/arm64/tagged-address-abi.rst @@ -44,8 +44,15 @@ The AArch64 Tagged Address ABI has two stages of relax= ation depending how the user addresses are used by the kernel: =20 1. User addresses not accessed by the kernel but used for address space - management (e.g. ``mmap()``, ``mprotect()``, ``madvise()``). The use - of valid tagged pointers in this context is always allowed. + management (e.g. ``mprotect()``, ``madvise()``). The use of valid + tagged pointers in this context is allowed with the exception of + ``brk()``, ``mmap()`` and the ``new_address`` argument to + ``mremap()`` as these have the potential of aliasing with existing + user addresses. + + NOTE: This behaviour changed in v5.6 and so some earlier kernels may + incorrectly accept valid tagged pointers for the ``brk()``, + ``mmap()`` and ``mremap()`` system calls. =20 2. User addresses accessed by the kernel (e.g. ``write()``). This ABI relaxation is disabled by default and the application thread needs to diff --git a/mm/mmap.c b/mm/mmap.c index 6756b8bb0033..d681a20eb4ea 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -195,8 +195,6 @@ SYSCALL_DEFINE1(brk, unsigned long, brk) bool downgraded =3D false; LIST_HEAD(uf); =20 - brk =3D untagged_addr(brk); - if (down_write_killable(&mm->mmap_sem)) return -EINTR; =20 @@ -1557,8 +1555,6 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, u= nsigned long len, struct file *file =3D NULL; unsigned long retval; =20 - addr =3D untagged_addr(addr); - if (!(flags & MAP_ANONYMOUS)) { audit_mmap_fd(fd, flags); file =3D fget(fd); diff --git a/mm/mremap.c b/mm/mremap.c index 122938dcec15..af363063ea23 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -607,7 +607,6 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned= long, old_len, LIST_HEAD(uf_unmap); =20 addr =3D untagged_addr(addr); - new_addr =3D untagged_addr(new_addr); =20 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE)) return ret;