From patchwork Mon Sep 11 15:27:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Salyzyn X-Patchwork-Id: 9947595 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 04B0B602C9 for ; Mon, 11 Sep 2017 15:28:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EF84228B37 for ; Mon, 11 Sep 2017 15:28:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E3BAA28BF2; Mon, 11 Sep 2017 15:28:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3946028B37 for ; Mon, 11 Sep 2017 15:28:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=4xe16fHBBKd/r3+GsKhZf/aBlMzAWIs9iKd16gmqfFs=; b=NE4 Z3Z8razzxKxoz8hv/o2DxWiVuJLbTYngJX3WM3ReRcVPrl4QHd/Om8vhylAmJ+Gn/5z1JpF39HQ3t Sge1LfZmpOUe9tpvmBV6EPMNmZKrUR9VsEcQZlT8QaO9HSrWIKPGFS0hsappVDC861c42aumxehzA QlkriR+htqpo6ChT50yiytTQmmAEUlbysonJpzcSAau6PtT09Kdh6P/OTN/FSgF4FvRvfE0V+CoE/ V2Sa8Nnj+LwSjV19HlnDuK8mjIlIiAaNv2d16TdGvQeQlegfeWw3iqhyo1ukhWtC4xOuEvV9Dej7Z Uh6G/p5hI32BAxDWRw4MFwly/x5+2+w==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1drQct-0002HE-KK; Mon, 11 Sep 2017 15:27:55 +0000 Received: from mail-pg0-x22b.google.com ([2607:f8b0:400e:c05::22b]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1drQcp-000215-KU for linux-arm-kernel@lists.infradead.org; Mon, 11 Sep 2017 15:27:54 +0000 Received: by mail-pg0-x22b.google.com with SMTP id i130so8487250pgc.3 for ; Mon, 11 Sep 2017 08:27:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=android.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=lSUccXuwac3t3QYbJ6TnoOYkAjbVnOMtk6Dwn4eSwZ8=; b=j0esFQ+7DzqHyrlJOMiSmzDQoadVpdu7T0uVwlTbyyp/xhOpdN6DZt84VWWoM6nw8E BPmJj3O2wSs5j1WLu0rQKVOFFT/LGHNN4gcPh4tDTuWsuFUCjRscaOomwb12FWpMJrfA gntzfpHqx/sQY9aGkaxoF3fBtivQ0LJQCbiJMYUf2n+dA4qWFAq+ZyhpHBpSHSdsMUyo WdIo9UymkfbuujKimbFMftf0rGGn+yGlngTE6RItZE3BCNppDKYFGZKW5kkhVyTRGtlR /ZtJFrXPC8Z94ohUIB8ZUOWhKb+saZ4BANJZaNVd54WyUiyjx3geGn6YBO0rGSj6JDXW DnAg== 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; bh=lSUccXuwac3t3QYbJ6TnoOYkAjbVnOMtk6Dwn4eSwZ8=; b=rh2HsYlgmcIVGFIUZJv9Fu0AQxj8/vI0CycRQR5aTH/0FfRecd2h+YlOpCx/zQBLrg vsuqGJdLKsqUaEdveH7GWl2KzPuKbWHWBmuNsERCrE7aFcZN9IYQzSRttXXWs2Jt4shn sqqrWDc9fXZBcUdJ0DxannascOEZeB+3+1Ao6ms7+07dTOYxRzm7S05VF63zxWMSZkNd SAxzBYOimz+8+ve2Pl+dQ1i9tjIzou6rDJVnKn8eljBnSRBk8+UYrqTSYCY1rqaV7bad EciIQbriTEwwxwkjidGjNiTwBR2Yj3xwdKfTxZHpXof43kphvsorQ4DGJiqKGRIcKvAR 75sw== X-Gm-Message-State: AHPjjUjy23lHTodRW1dS+btYJxWZoC1ANOWf4N1a9RpNjyOkGB7xs4RQ ZvMkb7LJVTVBIaiA X-Google-Smtp-Source: ADKCNb5Vtn7eZ//h/UzFUl7EEce8faCOt7ByVP7ttFmWeLfVUlvYqgsOmIHUQbT34wJ3/bSMxG6LZw== X-Received: by 10.99.115.21 with SMTP id o21mr12412081pgc.334.1505143650261; Mon, 11 Sep 2017 08:27:30 -0700 (PDT) Received: from nebulus.mtv.corp.google.com ([100.98.120.17]) by smtp.gmail.com with ESMTPSA id a19sm16313397pfj.88.2017.09.11.08.27.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 11 Sep 2017 08:27:29 -0700 (PDT) From: Mark Salyzyn To: linux-kernel@vger.kernel.org Subject: [PATCH v3 1/3] arm64: compat: Split the sigreturn trampolines and kuser helpers (C sources) Date: Mon, 11 Sep 2017 08:27:11 -0700 Message-Id: <20170911152719.95516-1-salyzyn@android.com> X-Mailer: git-send-email 2.14.1.581.gf28d330327-goog X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170911_082751_776365_675AC88F X-CRM114-Status: GOOD ( 18.88 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, peterz@infradead.org, catalin.marinas@arm.com, will.deacon@arm.com, mingo@kernel.org, zijun_hu@htc.com, jszhang@marvell.com, borntraeger@de.ibm.com, takahiro.akashi@linaro.org, labbott@redhat.com, Dave.Martin@arm.com, keescook@chromium.org, kevin.brodsky@arm.com, Scott Wood , mmarek@suse.com, john.stultz@linaro.org, linux-arm-kernel@lists.infradead.org, ard.biesheuvel@linaro.org, Dmitry Safonov , Mark Salyzyn , james.morse@arm.com, credmonster@gmail.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kevin Brodsky AArch32 processes are currently installed a special [vectors] page that contains the sigreturn trampolines and the kuser helpers, at the fixed address mandated by the kuser helpers ABI. Having both functionalities in the same page has become problematic, because: * It makes it impossible to disable the kuser helpers (the sigreturn trampolines cannot be removed), which is possible on arm. * A future 32-bit vDSO would provide the sigreturn trampolines itself, making those in [vectors] redundant. This patch addresses the problem by moving the sigreturn trampolines to a separate [sigpage] page, mirroring [sigpage] on arm. Even though [vectors] has always been a misnomer on arm64/compat, as there is no AArch32 vector there (and now only the kuser helpers), its name has been left unchanged, for compatibility with arm (there are reports of software relying on [vectors] being there as the last mapping in /proc/maps). mm->context.vdso used to point to the [vectors] page, which is unnecessary (as its address is fixed). It now points to the [sigpage] page (whose address is randomized like a vDSO). Signed-off-by: Kevin Brodsky Signed-off-by: Mark Salyzyn v2: - reduce churniness (and defer later to vDSO patches) - vectors_page and compat_vdso_spec as array of 2 - free sigpage if vectors allocation failed v3: - rebase --- arch/arm64/include/asm/processor.h | 4 +- arch/arm64/include/asm/signal32.h | 2 - arch/arm64/kernel/signal32.c | 5 +-- arch/arm64/kernel/vdso.c | 82 ++++++++++++++++++++++++++------------ 4 files changed, 60 insertions(+), 33 deletions(-) diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 29adab8138c3..a61609eca814 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -39,9 +39,9 @@ #define STACK_TOP_MAX TASK_SIZE_64 #ifdef CONFIG_COMPAT -#define AARCH32_VECTORS_BASE 0xffff0000 +#define AARCH32_KUSER_HELPERS_BASE 0xffff0000 #define STACK_TOP (test_thread_flag(TIF_32BIT) ? \ - AARCH32_VECTORS_BASE : STACK_TOP_MAX) + AARCH32_KUSER_HELPERS_BASE : STACK_TOP_MAX) #else #define STACK_TOP STACK_TOP_MAX #endif /* CONFIG_COMPAT */ diff --git a/arch/arm64/include/asm/signal32.h b/arch/arm64/include/asm/signal32.h index 81abea0b7650..58e288aaf0ba 100644 --- a/arch/arm64/include/asm/signal32.h +++ b/arch/arm64/include/asm/signal32.h @@ -20,8 +20,6 @@ #ifdef CONFIG_COMPAT #include -#define AARCH32_KERN_SIGRET_CODE_OFFSET 0x500 - int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set, struct pt_regs *regs); int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index 4e5a664be04b..bde7acb53c74 100644 --- a/arch/arm64/kernel/signal32.c +++ b/arch/arm64/kernel/signal32.c @@ -484,14 +484,13 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka, retcode = ptr_to_compat(ka->sa.sa_restorer); } else { /* Set up sigreturn pointer */ + void *sigreturn_base = current->mm->context.vdso; unsigned int idx = thumb << 1; if (ka->sa.sa_flags & SA_SIGINFO) idx += 3; - retcode = AARCH32_VECTORS_BASE + - AARCH32_KERN_SIGRET_CODE_OFFSET + - (idx << 2) + thumb; + retcode = ptr_to_compat(sigreturn_base) + (idx << 2) + thumb; } regs->regs[0] = usig; diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 2d419006ad43..544bbee5b447 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -1,5 +1,7 @@ /* - * VDSO implementation for AArch64 and vector page setup for AArch32. + * Additional userspace pages setup for AArch64 and AArch32. + * - AArch64: vDSO pages setup, vDSO data page update. + * - AArch32: sigreturn and kuser helpers pages setup. * * Copyright (C) 2012 ARM Limited * @@ -53,32 +55,51 @@ struct vdso_data *vdso_data = &vdso_data_store.data; /* * Create and map the vectors page for AArch32 tasks. */ -static struct page *vectors_page[1] __ro_after_init; +static struct page *vectors_page[] __ro_after_init; +static const struct vm_special_mapping compat_vdso_spec[] = { + { + /* Must be named [sigpage] for compatibility with arm. */ + .name = "[sigpage]", + .pages = &vectors_page[0], + }, + { + .name = "[kuserhelpers]", + .pages = &vectors_page[1], + }, +}; +static struct page *vectors_page[ARRAY_SIZE(compat_vdso_spec)] __ro_after_init; static int __init alloc_vectors_page(void) { extern char __kuser_helper_start[], __kuser_helper_end[]; - extern char __aarch32_sigret_code_start[], __aarch32_sigret_code_end[]; + size_t kuser_sz = __kuser_helper_end - __kuser_helper_start; + unsigned long kuser_vpage; - int kuser_sz = __kuser_helper_end - __kuser_helper_start; - int sigret_sz = __aarch32_sigret_code_end - __aarch32_sigret_code_start; - unsigned long vpage; - - vpage = get_zeroed_page(GFP_ATOMIC); + extern char __aarch32_sigret_code_start[], __aarch32_sigret_code_end[]; + size_t sigret_sz = + __aarch32_sigret_code_end - __aarch32_sigret_code_start; + unsigned long sigret_vpage; - if (!vpage) + sigret_vpage = get_zeroed_page(GFP_ATOMIC); + if (!sigret_vpage) return -ENOMEM; - /* kuser helpers */ - memcpy((void *)vpage + 0x1000 - kuser_sz, __kuser_helper_start, - kuser_sz); + kuser_vpage = get_zeroed_page(GFP_ATOMIC); + if (!kuser_vpage) { + free_page(sigret_vpage); + return -ENOMEM; + } /* sigreturn code */ - memcpy((void *)vpage + AARCH32_KERN_SIGRET_CODE_OFFSET, - __aarch32_sigret_code_start, sigret_sz); + memcpy((void *)sigret_vpage, __aarch32_sigret_code_start, sigret_sz); + flush_icache_range(sigret_vpage, sigret_vpage + PAGE_SIZE); + vectors_page[0] = virt_to_page(sigret_vpage); - flush_icache_range(vpage, vpage + PAGE_SIZE); - vectors_page[0] = virt_to_page(vpage); + /* kuser helpers */ + memcpy((void *)kuser_vpage + 0x1000 - kuser_sz, __kuser_helper_start, + kuser_sz); + flush_icache_range(kuser_vpage, kuser_vpage + PAGE_SIZE); + vectors_page[1] = virt_to_page(kuser_vpage); return 0; } @@ -87,23 +108,32 @@ arch_initcall(alloc_vectors_page); int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp) { struct mm_struct *mm = current->mm; - unsigned long addr = AARCH32_VECTORS_BASE; - static const struct vm_special_mapping spec = { - .name = "[vectors]", - .pages = vectors_page, - - }; + unsigned long addr; void *ret; if (down_write_killable(&mm->mmap_sem)) return -EINTR; - current->mm->context.vdso = (void *)addr; + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); + if (IS_ERR_VALUE(addr)) { + ret = ERR_PTR(addr); + goto out; + } - /* Map vectors page at the high address. */ ret = _install_special_mapping(mm, addr, PAGE_SIZE, - VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC, - &spec); + VM_READ|VM_EXEC| + VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, + &compat_vdso_spec[0]); + if (IS_ERR(ret)) + goto out; + current->mm->context.vdso = (void *)addr; + + /* Map the kuser helpers at the ABI-defined high address. */ + ret = _install_special_mapping(mm, AARCH32_KUSER_HELPERS_BASE, + PAGE_SIZE, + VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC, + &compat_vdso_spec[1]); +out: up_write(&mm->mmap_sem); return PTR_ERR_OR_ZERO(ret);