From patchwork Wed Aug 16 22:26:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Salyzyn X-Patchwork-Id: 9904681 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 55F9D600CA for ; Wed, 16 Aug 2017 22:28:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 451AE28A6C for ; Wed, 16 Aug 2017 22:28:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3920328A6E; Wed, 16 Aug 2017 22:28:28 +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=-2.6 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_LOW 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 80FB328A6C for ; Wed, 16 Aug 2017 22:28:27 +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=XBFLiHeaw9kIaf8VgYzmRYeW8tkgAvnUT1VGfq2D0hE=; b=O5Y zY89Liz/IbO/rqU8KCrFB1repETmLCirklDh8scnV9cDTfAiVejodLnr1PQ647I7xBPvvXu7Vi+0j LJrUGH3Mky8yA14cf+dzZAuzmDhsAOCdrZedb6SVAT6+pln9RRA7cuOb8TzehVCrOeZsAzOtcBVIW sRPcJR5TkurBVtBRekrlOOIXAYGmMTWoNdCydBp4al2qxQKIlUgVkjlkrlXi9QqXGxRu2kB0uvcdr EM+bUPeNTw+RSr6g6U1onJ3s7tAsWHfVmD808jhvIw8EC71TPfwsRf5WdHF7w4N4dld2+WZK1q6zT 5oMdDftUl3mbKRpirOk1GJ6OnoezGzg==; 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 1di6nI-00020q-7J; Wed, 16 Aug 2017 22:28:08 +0000 Received: from mail-pg0-x229.google.com ([2607:f8b0:400e:c05::229]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1di6nF-0001ZU-5p for linux-arm-kernel@lists.infradead.org; Wed, 16 Aug 2017 22:28:07 +0000 Received: by mail-pg0-x229.google.com with SMTP id v189so29754594pgd.2 for ; Wed, 16 Aug 2017 15:27:44 -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=DUJ7pisT28X0G6/tif87axnxryHbOjrdSqKB+tIoXx0=; b=eLiGDvX6/ZE4Wo77SvW6fpySD/h0ClbnvHEVylpDZ3DUKO1K1kpHgmUe9FNddVFN1a P73S1MnQVnlRlJVFix7RHBJVZ4yz7DtqLqQd9J+Jf0rID3VLW9lYamoSMRYMXFAswvOe mOg/HNgwpBmBmK4xi7GQ2lmo1a6xa/iTlGX8/d4jV+7V9kT/+OtiIa+o4r84r71k0ojk 5afmeDyfGBtJFMbovTN/9uvUZY3rGbdeAqkCA6W1XK9vfFgKWr73CuRqBqvRM5gJPc64 bJddheuuSLHaW+0/ULt0FKq6qSom7kwKaMTzEtdVgYwhtR9VBS9N4g2JT0g2LBlQfYnz NvGA== 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=DUJ7pisT28X0G6/tif87axnxryHbOjrdSqKB+tIoXx0=; b=TJdoDGw/kTnlyXXZiqZrbWKcHQdZmCoG3S9P5xIlFN/gIzLkNiZnoKVp6iq9KBrhRt pZnRb9aJ59llm67Kuiq/Qg8h1Gcb45UAY67utSaOxWdY7xYo0Pmg/jWZywTTnVrhcg6g XOqoXHsvyXwCw27jWC+kKKsN0t38u7NEiVUYsqWC564120yPCzR9Yh3AnSWjdvlsyjhT iJTaMq26FUk+4M2RV1av3tP6MiJhg+dR+bfw/FRo8zescQjcCBDqvoVi8wne6zA7xovC Iiqy0HzHCVPh4zC/EK2xLaNPhik3IlyMe/+XSMW4B5YHLkSCseokvU0bzreX/w8i3ga9 QlsQ== X-Gm-Message-State: AHYfb5jiQ9+8pPBEncNKiaLFO+a7BxBfPeDY3jTJ9maReBo794sax5+t TSlpEvNGJsU7b0a8 X-Received: by 10.84.231.204 with SMTP id g12mr3533088pln.131.1502922463596; Wed, 16 Aug 2017 15:27:43 -0700 (PDT) Received: from nebulus.mtv.corp.google.com ([100.98.120.17]) by smtp.gmail.com with ESMTPSA id a22sm158470pfj.94.2017.08.16.15.27.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 16 Aug 2017 15:27:43 -0700 (PDT) From: Mark Salyzyn To: linux-kernel@vger.kernel.org Subject: [PATCH v2 1/3] arm64: compat: Split the sigreturn trampolines and kuser helpers (C sources) Date: Wed, 16 Aug 2017 15:26:59 -0700 Message-Id: <20170816222723.118839-1-salyzyn@android.com> X-Mailer: git-send-email 2.14.1.480.gb18f417b89-goog X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170816_152805_388019_62006652 X-CRM114-Status: GOOD ( 19.42 ) 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 , Jisheng Zhang , John Stultz , Kees Cook , "Peter Zijlstra \(Intel\)" , Catalin Marinas , Kevin Brodsky , Will Deacon , Mark Salyzyn , Christian Borntraeger , James Morse , linux-arm-kernel@lists.infradead.org, Chris Redmon , Laura Abbott , Ingo Molnar , zijun_hu , Dave Martin 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) - vctors_page and compat_vdso_spec as array of 2 - free sigpage if vectors allocation failed --- 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 64c9e78f9882..70ac0ceef306 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 eeaa97559bab..49896b9c161e 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 - extern const compat_ulong_t aarch32_sigret_code[6]; int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set, diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index c747a0fc5d7d..3f4c5adb244e 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 e8f759f764f2..3777f232c18e 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);