Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3733170imu; Mon, 7 Jan 2019 08:29:32 -0800 (PST) X-Google-Smtp-Source: ALg8bN5BDfUdk5ugJ8DMvQKcG8Okbh5u6k9yLg7xmdPJpFv6UkZsEmQQhuCE1ygXh0rVRdcRYTC0 X-Received: by 2002:a63:9402:: with SMTP id m2mr11096789pge.93.1546878572197; Mon, 07 Jan 2019 08:29:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1546878572; cv=none; d=google.com; s=arc-20160816; b=g6corOcyXJIbUMkcX/slhOyAKSIrTPzjAcwX3C4hFONjARxbflQFtN0SSwk6QEiCG4 mNPYKmFtCepxVW/3t7HKZjssRgXwlmcyqBJ4BlvJMqja8vwJU6YWjprLSQzBuYuZi3VH fcPX9tr5sgshNYa3paSn+lZpsR6ZgqKnUlQYpRW1tvZa5esXcvARBFU5EsHE+Vs3gZBF eD9Qqs/20OW0AQi5jiuxWTXQSLNagM60nefZHbHs0MXz8txl7V/cfeDJZ2L5pRheOegX K0U5ecykJnJDnOEGAZRtUbfpjduMTxLurIgijkyPVpCl+OLYloHzqDPkZYnxEe9tb5b0 yiQw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=701zALNAnhuSAA4RieBcwsqpfiaOVcX0EjBjOQeBPhU=; b=f7PQgzd02z3AEpff95eOwKjZBrltkPmtjGouU1dAfzx0qx2rUqFP2JSQ+VKJSClEOX xKdQS44+IemLk6C4RRx2L4FhWRXtWK/28T0vcsp27prz918sYA4yic0wBeVnqGodACRR v2X4KmGRtCoUyFVbfkX+pXw6TeN3FLUg48c8cQR3hTGne3u4ONXrYgHxJ7zlC5ogqZwu WeW0+ug8nk91feGoZI81Q2L7HMsVrq7UaXARiZigVzfMlVZwu2aJthb7OaADZB5+yv2c Y7vX5ZXJBW3LncaMcZLL0XbBleEwaxtiNxZCuiGh4he/SmHDjeaqNXSXK88RX/Ao9mCd 2EKw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=tgHlz1FV; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s12si4177030pgh.395.2019.01.07.08.29.16; Mon, 07 Jan 2019 08:29:32 -0800 (PST) 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=@kernel.org header.s=default header.b=tgHlz1FV; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730775AbfAGNNX (ORCPT + 99 others); Mon, 7 Jan 2019 08:13:23 -0500 Received: from mail.kernel.org ([198.145.29.99]:51276 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730260AbfAGNDr (ORCPT ); Mon, 7 Jan 2019 08:03:47 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id AFEBB217D4; Mon, 7 Jan 2019 13:03:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1546866226; bh=bSBPiChESolQeq7V5JlUqU/PADOZUi0/BwfhDFgdAZQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tgHlz1FVnurUDH7U0lBg1aKG8aKxgjOlhrMQe28Pk+EexzFbJiqCAJ3Fr9/5KQFyk 8pfw/G+CN2cXC1Svs7Tt2NCba9J4HEGkTEvTIvJ2sVoA/WinKCoapkmdNZ6ekEmCBg d6xPHXrZuebLwD3LgaxcM7+29nyi6kNLgnBqVh7c= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Andy Lutomirski , Paul Burton , linux-mips@vger.kernel.org, Rich Felker , David Daney Subject: [PATCH 4.14 089/101] MIPS: math-emu: Write-protect delay slot emulation pages Date: Mon, 7 Jan 2019 13:33:17 +0100 Message-Id: <20190107105337.745058069@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107105330.372621917@linuxfoundation.org> References: <20190107105330.372621917@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Paul Burton commit adcc81f148d733b7e8e641300c5590a2cdc13bf3 upstream. Mapping the delay slot emulation page as both writeable & executable presents a security risk, in that if an exploit can write to & jump into the page then it can be used as an easy way to execute arbitrary code. Prevent this by mapping the page read-only for userland, and using access_process_vm() with the FOLL_FORCE flag to write to it from mips_dsemul(). This will likely be less efficient due to copy_to_user_page() performing cache maintenance on a whole page, rather than a single line as in the previous use of flush_cache_sigtramp(). However this delay slot emulation code ought not to be running in any performance critical paths anyway so this isn't really a problem, and we can probably do better in copy_to_user_page() anyway in future. A major advantage of this approach is that the fix is small & simple to backport to stable kernels. Reported-by: Andy Lutomirski Signed-off-by: Paul Burton Fixes: 432c6bacbd0c ("MIPS: Use per-mm page to execute branch delay slot instructions") Cc: stable@vger.kernel.org # v4.8+ Cc: linux-mips@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: Rich Felker Cc: David Daney Signed-off-by: Greg Kroah-Hartman --- arch/mips/kernel/vdso.c | 4 ++-- arch/mips/math-emu/dsemul.c | 38 ++++++++++++++++++++------------------ 2 files changed, 22 insertions(+), 20 deletions(-) --- a/arch/mips/kernel/vdso.c +++ b/arch/mips/kernel/vdso.c @@ -126,8 +126,8 @@ int arch_setup_additional_pages(struct l /* Map delay slot emulation page */ base = mmap_region(NULL, STACK_TOP, PAGE_SIZE, - VM_READ|VM_WRITE|VM_EXEC| - VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, + VM_READ | VM_EXEC | + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC, 0, NULL); if (IS_ERR_VALUE(base)) { ret = base; --- a/arch/mips/math-emu/dsemul.c +++ b/arch/mips/math-emu/dsemul.c @@ -214,8 +214,9 @@ int mips_dsemul(struct pt_regs *regs, mi { int isa16 = get_isa16_mode(regs->cp0_epc); mips_instruction break_math; - struct emuframe __user *fr; - int err, fr_idx; + unsigned long fr_uaddr; + struct emuframe fr; + int fr_idx, ret; /* NOP is easy */ if (ir == 0) @@ -250,27 +251,31 @@ int mips_dsemul(struct pt_regs *regs, mi fr_idx = alloc_emuframe(); if (fr_idx == BD_EMUFRAME_NONE) return SIGBUS; - fr = &dsemul_page()[fr_idx]; /* Retrieve the appropriately encoded break instruction */ break_math = BREAK_MATH(isa16); /* Write the instructions to the frame */ if (isa16) { - err = __put_user(ir >> 16, - (u16 __user *)(&fr->emul)); - err |= __put_user(ir & 0xffff, - (u16 __user *)((long)(&fr->emul) + 2)); - err |= __put_user(break_math >> 16, - (u16 __user *)(&fr->badinst)); - err |= __put_user(break_math & 0xffff, - (u16 __user *)((long)(&fr->badinst) + 2)); + union mips_instruction _emul = { + .halfword = { ir >> 16, ir } + }; + union mips_instruction _badinst = { + .halfword = { break_math >> 16, break_math } + }; + + fr.emul = _emul.word; + fr.badinst = _badinst.word; } else { - err = __put_user(ir, &fr->emul); - err |= __put_user(break_math, &fr->badinst); + fr.emul = ir; + fr.badinst = break_math; } - if (unlikely(err)) { + /* Write the frame to user memory */ + fr_uaddr = (unsigned long)&dsemul_page()[fr_idx]; + ret = access_process_vm(current, fr_uaddr, &fr, sizeof(fr), + FOLL_FORCE | FOLL_WRITE); + if (unlikely(ret != sizeof(fr))) { MIPS_FPU_EMU_INC_STATS(errors); free_emuframe(fr_idx, current->mm); return SIGBUS; @@ -282,10 +287,7 @@ int mips_dsemul(struct pt_regs *regs, mi atomic_set(¤t->thread.bd_emu_frame, fr_idx); /* Change user register context to execute the frame */ - regs->cp0_epc = (unsigned long)&fr->emul | isa16; - - /* Ensure the icache observes our newly written frame */ - flush_cache_sigtramp((unsigned long)&fr->emul); + regs->cp0_epc = fr_uaddr | isa16; return 0; }