Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp3709484ybv; Mon, 10 Feb 2020 05:06:54 -0800 (PST) X-Google-Smtp-Source: APXvYqxuFaFNpiA687TpbQly0Kml5H8YciPFTbFD1EqyGgpK7/S/R/DsdQBlwx1HpoSeFwqfTBGg X-Received: by 2002:a05:6830:22c3:: with SMTP id q3mr941339otc.335.1581340014027; Mon, 10 Feb 2020 05:06:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1581340014; cv=none; d=google.com; s=arc-20160816; b=klC3cPq0BoY21gEKOqqHq3Rq2Ka0MhwD2QdZfhwe5E+coy4NqQLtnN0O5sULNiVS7b 0VZ+if7Tk4U0H9gMbD012DV3RMy2SbGUdJeJFt1HU+H9BpNm7z3d0cbqmvAfNmLvoCxj z46Yg0v4lg+MqFxaWkGwZF1e0A6HNBCiP05w/6LQn5qnLD6yJjm5Le2J2JmCVK/Ki8bn W7btrgUQ4OmroR/6aw4rv+wBQ/yDNldIlFsB+37SoN709k+JGLJ2zk+SJ3gP8i4nLJEo oaumCopAVDF2DWv9GP0lqvWd0+L+opZoIeqj5OBS/U0BaXKcSn9p23iTJGDG5yXt/qJn NKxA== 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=z6l2orqzqX2D7dkrG4EpJxWYnm8gax5WbMRxr+7ZA34=; b=gBGZUnAspxQoLRLDi2+JjO3YpB3PhnCCfp0u7w12YwMmLlHFXOoU3uBENVw+TkahN4 OfNIs4GL4elJmvgo7I9chrrq0/lpgbtaGBm6RRfflVgmcNkGylMwSqd83L2+A1cBcUfn gtgUH6I7TetJ/K98WlP25DXHOpQMcrMZiMKZMOgSIGhVZC5VhcuE8QGiatuDywQw9+2b DJZlK6IKMDpgUnyM3QpcG5iskVUtr51khrJCqFjjCBohWGbDUiINLOpy91QrtNV8/3CI fszL1rJ6DzakBCPCDiA/lJ90zDNzNA7JI6oXw6srBR6yCm87k1f9xoUqnVZfEECp0nJb 8FZA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=y+DqP6E5; 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 a3si167946oib.168.2020.02.10.05.06.42; Mon, 10 Feb 2020 05:06:54 -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=y+DqP6E5; 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 S1729936AbgBJNG0 (ORCPT + 99 others); Mon, 10 Feb 2020 08:06:26 -0500 Received: from mail.kernel.org ([198.145.29.99]:38594 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728743AbgBJMjy (ORCPT ); Mon, 10 Feb 2020 07:39:54 -0500 Received: from localhost (unknown [209.37.97.194]) (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 9698124682; Mon, 10 Feb 2020 12:39:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1581338393; bh=1LagMrR2JDNREVeXuyYCHH90b+aBTf6vzRc79Tycbls=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=y+DqP6E55c9/uQtGCSS7KfYTg2j+rwetMmZVypt+BsX+amiKiBQpETN5d+NxmrWms PhyQqMIBVdlZ0LP9b3RynKe7VdVkcBysUZ9+k/Rfg7gZcTxKWJyAFeFHMyAt+FrTHT C6pY+0ZZAty4DpY9NriOvbpvdK+W9ktk8GEcIDYk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Christophe Leroy , Michael Ellerman Subject: [PATCH 5.5 087/367] powerpc/32s: Fix bad_kuap_fault() Date: Mon, 10 Feb 2020 04:30:00 -0800 Message-Id: <20200210122432.393957091@linuxfoundation.org> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200210122423.695146547@linuxfoundation.org> References: <20200210122423.695146547@linuxfoundation.org> User-Agent: quilt/0.66 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 From: Christophe Leroy commit 6ec20aa2e510b6297906c45f009aa08b2d97269a upstream. At the moment, bad_kuap_fault() reports a fault only if a bad access to userspace occurred while access to userspace was not granted. But if a fault occurs for a write outside the allowed userspace segment(s) that have been unlocked, bad_kuap_fault() fails to detect it and the kernel loops forever in do_page_fault(). Fix it by checking that the accessed address is within the allowed range. Fixes: a68c31fc01ef ("powerpc/32s: Implement Kernel Userspace Access Protection") Cc: stable@vger.kernel.org # v5.2+ Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/f48244e9485ada0a304ed33ccbb8da271180c80d.1579866752.git.christophe.leroy@c-s.fr Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/include/asm/book3s/32/kup.h | 9 +++++++-- arch/powerpc/include/asm/book3s/64/kup-radix.h | 3 ++- arch/powerpc/include/asm/kup.h | 6 +++++- arch/powerpc/include/asm/nohash/32/kup-8xx.h | 3 ++- arch/powerpc/mm/fault.c | 2 +- 5 files changed, 17 insertions(+), 6 deletions(-) --- a/arch/powerpc/include/asm/book3s/32/kup.h +++ b/arch/powerpc/include/asm/book3s/32/kup.h @@ -131,12 +131,17 @@ static inline void prevent_user_access(v kuap_update_sr(mfsrin(addr) | SR_KS, addr, end); /* set Ks */ } -static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write) +static inline bool +bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) { + unsigned long begin = regs->kuap & 0xf0000000; + unsigned long end = regs->kuap << 28; + if (!is_write) return false; - return WARN(!regs->kuap, "Bug: write fault blocked by segment registers !"); + return WARN(address < begin || address >= end, + "Bug: write fault blocked by segment registers !"); } #endif /* CONFIG_PPC_KUAP */ --- a/arch/powerpc/include/asm/book3s/64/kup-radix.h +++ b/arch/powerpc/include/asm/book3s/64/kup-radix.h @@ -95,7 +95,8 @@ static inline void prevent_user_access(v set_kuap(AMR_KUAP_BLOCKED); } -static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write) +static inline bool +bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) { return WARN(mmu_has_feature(MMU_FTR_RADIX_KUAP) && (regs->kuap & (is_write ? AMR_KUAP_BLOCK_WRITE : AMR_KUAP_BLOCK_READ)), --- a/arch/powerpc/include/asm/kup.h +++ b/arch/powerpc/include/asm/kup.h @@ -45,7 +45,11 @@ static inline void allow_user_access(voi unsigned long size) { } static inline void prevent_user_access(void __user *to, const void __user *from, unsigned long size) { } -static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write) { return false; } +static inline bool +bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) +{ + return false; +} #endif /* CONFIG_PPC_KUAP */ static inline void allow_read_from_user(const void __user *from, unsigned long size) --- a/arch/powerpc/include/asm/nohash/32/kup-8xx.h +++ b/arch/powerpc/include/asm/nohash/32/kup-8xx.h @@ -46,7 +46,8 @@ static inline void prevent_user_access(v mtspr(SPRN_MD_AP, MD_APG_KUAP); } -static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write) +static inline bool +bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) { return WARN(!((regs->kuap ^ MD_APG_KUAP) & 0xf0000000), "Bug: fault blocked by AP register !"); --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -233,7 +233,7 @@ static bool bad_kernel_fault(struct pt_r // Read/write fault in a valid region (the exception table search passed // above), but blocked by KUAP is bad, it can never succeed. - if (bad_kuap_fault(regs, is_write)) + if (bad_kuap_fault(regs, address, is_write)) return true; // What's left? Kernel fault on user in well defined regions (extable