Received: by 2002:ac0:bc90:0:0:0:0:0 with SMTP id a16csp640653img; Wed, 20 Mar 2019 07:57:06 -0700 (PDT) X-Google-Smtp-Source: APXvYqxxjeHuMhPz3A2pur2Tyte/0760UtzywOUh8+Qyfy4yHTBMO2ZRRR7h3um029k6EC8y+aLu X-Received: by 2002:a62:a113:: with SMTP id b19mr30268520pff.227.1553093825985; Wed, 20 Mar 2019 07:57:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1553093825; cv=none; d=google.com; s=arc-20160816; b=1DaQ0Clu6vioeBrXX8aE4TAUFOOlV+DU+WU7EBYMA5Ia9TeYrj5S/Q7Xzk2fyRFC+c lLEIGRHDD1WDfhijQ+Dk5t+7gY1REeIEI0vfW5gLRx30OcVw6+0KVGoVdkvb0jfp+nyU jdpCOcIGk5QHw+gUNXFrMUFyhaU09jWbWCXASQvy5L9nJHR6tz796KrldxtnrXIDz7zt 4E+0exL7bZQKlc/VrrMV7ogIQUomIZQi3qeI4CwrxFZa3g/MgSPEGisaedETL828nfyO maHKnIMYVaO5KUoRDGK8EcApkFjmIKkgPtBwlq3xFEmmWypIaFlprevfLmuw8ZCrgb08 ggkg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:dkim-signature; bh=SRoxSUqmsB49A1VVgrFKE/I4A7Rwq9IqNVIi8CfykWo=; b=wFFfoYcf9BkoEZc90/5svg/xIcf540NUcWfSQE2e+KqEvFb02XXEuw0aN6Ekuhcq9q UnxneH3XgpNmdYeuz1Z3vGhYDszElZDQQOwnXDiztWl9lIR1oKzR+NAyGDPy87UjIBsN GEVut/hUu4tkrl/4Bdp98+1yQkyLN7q4r/tHmKkzCTIS0zAvgKzXLDJtgtUKaQQydHhz Xa9VCHfbkQvDTfaXIzfY6gfjYZbGFnTt2d9bKdobnRnJjxXi+Je7i+m2/Ywz3KETD6jl iZ/Y3xobRwgeso8kRQsdE6rioGsNtfc76UOlpo/z1dDA9VqfyLXiFoq/qo5lFmE0Mw1f shNw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b="OyzBlC0/"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n9si1867460pgc.472.2019.03.20.07.56.50; Wed, 20 Mar 2019 07:57:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b="OyzBlC0/"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728405AbfCTOv7 (ORCPT + 99 others); Wed, 20 Mar 2019 10:51:59 -0400 Received: from mail-vs1-f73.google.com ([209.85.217.73]:41982 "EHLO mail-vs1-f73.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728367AbfCTOv5 (ORCPT ); Wed, 20 Mar 2019 10:51:57 -0400 Received: by mail-vs1-f73.google.com with SMTP id a23so854102vsd.8 for ; Wed, 20 Mar 2019 07:51:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=SRoxSUqmsB49A1VVgrFKE/I4A7Rwq9IqNVIi8CfykWo=; b=OyzBlC0/uL5vE1MbnBSsgcN7+jbpmXNZtGY60kuBUM0zSFrlGT3CrF5ZT1ZCmJ+hRs B2xng/DpfUZY14vvFMcs+OKuTagQXLSbgUcYCZYD8lCRYocjoE+F6dis/azC0n2LahpR fhCbNmj7Sko0sq6SmJ01y5agfyxEJGwen1uXCSzTgtop3qk/9OMZRX0iJ2jvu1LdnV9D 9KURQrsliO8cca++/6z/5DZO7j5DvF4rmS/X5lt30BPgDAJvqld664x1IsGKsEwB6tZO V65ycbY/8qFjv73eCrvAa8au6tfc73nlS7Q4r5OSfX539V26tciuYc2xjorJhbhq7f9n jsQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=SRoxSUqmsB49A1VVgrFKE/I4A7Rwq9IqNVIi8CfykWo=; b=J1PJ5SszmeFydN87CDyBo90VYkLNUiNDGKXBXdxdbj7Wfw/0rDiLja8dgDHqAGNYik wKJBSRen7FHSgHUMlAQgey2H7sGwFHt4sIPyvKY2kUnSoKlR50PmjcYVDGQ2PEDxcmla UugGKnEvj5R7kp7SWIpLLLa9gok4QTwJXvc9q3pvCN5PldWkgCCHMiWUZDEoep3mx39+ v4tn9QhMnsyf87qOWi1E+jef88OZNdEH0GMp8C4OEbpFQ6iY7i5ua0FPnglGOKZxluRB 4HGdDlcUqlijrlUMlrRItEfqEM10EOpg117cd7NY5TZWCagS0mfLPM6NztYKw6eY1mz0 2Ejw== X-Gm-Message-State: APjAAAWUUCAGgkl2fyl12cmYEaZ8M3EuxnH/s3ijb+pQvJI1ll/Jmk0g NGz81ByupSkqfX9ap3LC+TM5SLANDwpKdL6G X-Received: by 2002:a1f:9644:: with SMTP id y65mr16461102vkd.23.1553093516273; Wed, 20 Mar 2019 07:51:56 -0700 (PDT) Date: Wed, 20 Mar 2019 15:51:18 +0100 In-Reply-To: Message-Id: <44ad2d0c55dbad449edac23ae46d151a04102a1d.1553093421.git.andreyknvl@google.com> Mime-Version: 1.0 References: X-Mailer: git-send-email 2.21.0.225.g810b269d1ac-goog Subject: [PATCH v13 04/20] mm, arm64: untag user pointers passed to memory syscalls From: Andrey Konovalov To: Catalin Marinas , Will Deacon , Mark Rutland , Robin Murphy , Kees Cook , Kate Stewart , Greg Kroah-Hartman , Andrew Morton , Ingo Molnar , "Kirill A . Shutemov" , Shuah Khan , Vincenzo Frascino , Eric Dumazet , "David S. Miller" , Alexei Starovoitov , Daniel Borkmann , Steven Rostedt , Ingo Molnar , Peter Zijlstra , Arnaldo Carvalho de Melo , Alex Deucher , "=?UTF-8?q?Christian=20K=C3=B6nig?=" , "David (ChunMing) Zhou" , Yishai Hadas , Mauro Carvalho Chehab , Jens Wiklander , Alex Williamson , linux-arm-kernel@lists.infradead.org, linux-mm@kvack.org, linux-arch@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-rdma@vger.kernel.org, linux-media@vger.kernel.org, kvm@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Dmitry Vyukov , Kostya Serebryany , Evgeniy Stepanov , Lee Smith , Ramana Radhakrishnan , Jacob Bramley , Ruben Ayrapetyan , Chintan Pandya , Luc Van Oostenryck , Dave Martin , Kevin Brodsky , Szabolcs Nagy , Andrey Konovalov Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch is a part of a series that extends arm64 kernel ABI to allow to pass tagged user pointers (with the top byte set to something else other than 0x00) as syscall arguments. This patch allows tagged pointers to be passed to the following memory syscalls: madvise, mbind, get_mempolicy, mincore, mlock, mlock2, brk, mmap_pgoff, old_mmap, munmap, remap_file_pages, mprotect, pkey_mprotect, mremap, msync and shmdt. This is done by untagging pointers passed to these syscalls in the prologues of their handlers. Signed-off-by: Andrey Konovalov --- ipc/shm.c | 2 ++ mm/madvise.c | 2 ++ mm/mempolicy.c | 5 +++++ mm/migrate.c | 1 + mm/mincore.c | 2 ++ mm/mlock.c | 5 +++++ mm/mmap.c | 7 +++++++ mm/mprotect.c | 1 + mm/mremap.c | 2 ++ mm/msync.c | 2 ++ 10 files changed, 29 insertions(+) diff --git a/ipc/shm.c b/ipc/shm.c index ce1ca9f7c6e9..7af8951e6c41 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -1593,6 +1593,7 @@ SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg) unsigned long ret; long err; + shmaddr = untagged_addr(shmaddr); err = do_shmat(shmid, shmaddr, shmflg, &ret, SHMLBA); if (err) return err; @@ -1732,6 +1733,7 @@ long ksys_shmdt(char __user *shmaddr) SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) { + shmaddr = untagged_addr(shmaddr); return ksys_shmdt(shmaddr); } diff --git a/mm/madvise.c b/mm/madvise.c index 21a7881a2db4..64e6d34a7f9b 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -809,6 +809,8 @@ SYSCALL_DEFINE3(madvise, unsigned long, start, size_t, len_in, int, behavior) size_t len; struct blk_plug plug; + start = untagged_addr(start); + if (!madvise_behavior_valid(behavior)) return error; diff --git a/mm/mempolicy.c b/mm/mempolicy.c index af171ccb56a2..31691737c59c 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1334,6 +1334,7 @@ static long kernel_mbind(unsigned long start, unsigned long len, int err; unsigned short mode_flags; + start = untagged_addr(start); mode_flags = mode & MPOL_MODE_FLAGS; mode &= ~MPOL_MODE_FLAGS; if (mode >= MPOL_MAX) @@ -1491,6 +1492,8 @@ static int kernel_get_mempolicy(int __user *policy, int uninitialized_var(pval); nodemask_t nodes; + addr = untagged_addr(addr); + if (nmask != NULL && maxnode < nr_node_ids) return -EINVAL; @@ -1576,6 +1579,8 @@ COMPAT_SYSCALL_DEFINE6(mbind, compat_ulong_t, start, compat_ulong_t, len, unsigned long nr_bits, alloc_size; nodemask_t bm; + start = untagged_addr(start); + nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES); alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; diff --git a/mm/migrate.c b/mm/migrate.c index ac6f4939bb59..ecc6dcdefb1f 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1612,6 +1612,7 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes, if (get_user(node, nodes + i)) goto out_flush; addr = (unsigned long)p; + addr = untagged_addr(addr); err = -ENODEV; if (node < 0 || node >= MAX_NUMNODES) diff --git a/mm/mincore.c b/mm/mincore.c index 218099b5ed31..c4a3f4484b6b 100644 --- a/mm/mincore.c +++ b/mm/mincore.c @@ -228,6 +228,8 @@ SYSCALL_DEFINE3(mincore, unsigned long, start, size_t, len, unsigned long pages; unsigned char *tmp; + start = untagged_addr(start); + /* Check the start address: needs to be page-aligned.. */ if (start & ~PAGE_MASK) return -EINVAL; diff --git a/mm/mlock.c b/mm/mlock.c index 080f3b36415b..6934ec92bf39 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -715,6 +715,7 @@ static __must_check int do_mlock(unsigned long start, size_t len, vm_flags_t fla SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len) { + start = untagged_addr(start); return do_mlock(start, len, VM_LOCKED); } @@ -722,6 +723,8 @@ SYSCALL_DEFINE3(mlock2, unsigned long, start, size_t, len, int, flags) { vm_flags_t vm_flags = VM_LOCKED; + start = untagged_addr(start); + if (flags & ~MLOCK_ONFAULT) return -EINVAL; @@ -735,6 +738,8 @@ SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len) { int ret; + start = untagged_addr(start); + len = PAGE_ALIGN(len + (offset_in_page(start))); start &= PAGE_MASK; diff --git a/mm/mmap.c b/mm/mmap.c index 41eb48d9b527..512c679c7f33 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -199,6 +199,8 @@ SYSCALL_DEFINE1(brk, unsigned long, brk) bool downgraded = false; LIST_HEAD(uf); + brk = untagged_addr(brk); + if (down_write_killable(&mm->mmap_sem)) return -EINTR; @@ -1571,6 +1573,8 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, struct file *file = NULL; unsigned long retval; + addr = untagged_addr(addr); + if (!(flags & MAP_ANONYMOUS)) { audit_mmap_fd(fd, flags); file = fget(fd); @@ -2867,6 +2871,7 @@ EXPORT_SYMBOL(vm_munmap); SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { + addr = untagged_addr(addr); profile_munmap(addr); return __vm_munmap(addr, len, true); } @@ -2885,6 +2890,8 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, unsigned long ret = -EINVAL; struct file *file; + start = untagged_addr(start); + pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst.\n", current->comm, current->pid); diff --git a/mm/mprotect.c b/mm/mprotect.c index 028c724dcb1a..3c2b11629f89 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -468,6 +468,7 @@ static int do_mprotect_pkey(unsigned long start, size_t len, if (grows == (PROT_GROWSDOWN|PROT_GROWSUP)) /* can't be both */ return -EINVAL; + start = untagged_addr(start); if (start & ~PAGE_MASK) return -EINVAL; if (!len) diff --git a/mm/mremap.c b/mm/mremap.c index e3edef6b7a12..6422aeee65bb 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -605,6 +605,8 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, LIST_HEAD(uf_unmap_early); LIST_HEAD(uf_unmap); + addr = untagged_addr(addr); + if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE)) return ret; diff --git a/mm/msync.c b/mm/msync.c index ef30a429623a..c3bd3e75f687 100644 --- a/mm/msync.c +++ b/mm/msync.c @@ -37,6 +37,8 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags) int unmapped_error = 0; int error = -EINVAL; + start = untagged_addr(start); + if (flags & ~(MS_ASYNC | MS_INVALIDATE | MS_SYNC)) goto out; if (offset_in_page(start)) -- 2.21.0.225.g810b269d1ac-goog