Received: by 2002:a25:683:0:0:0:0:0 with SMTP id 125csp667778ybg; Mon, 1 Jun 2020 11:12:09 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyj5y9FlsWrld+xMuG5C+129cdJoOQ2Qvb1Mx7oX+VTDKa5PFakUC4O2QuPY+LmUHLzsmOS X-Received: by 2002:aa7:dace:: with SMTP id x14mr9802410eds.343.1591035129048; Mon, 01 Jun 2020 11:12:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1591035129; cv=none; d=google.com; s=arc-20160816; b=RW9r2PArh11GtMdIvAmS9W82Apxx7gYdUzp+EFnVnjg7WNCoWI2pe+3RVC5Pa9mZfg arD9XUco4dKIQg9vz7/JgfxnvnE48hiUA4ZQYWk8jNIpeIlwnQ0gnbFrHM4ewYffHVK5 u9JSxkT0NhoziXllfoBX6sE/aUvrO9/2QaLqJrEAMUfUEsXRNgWslbSYPjlJqmjhDgLq cgKeKWqRLiFKXG81PNmnnmCDes71OdBALzSjAsYEEd3TxeF4+RkTXRt+azfj89s9gjhV 8vb9Bb5FuIH4lGXmVvsHiY1VhmP7Khlr7r1KPu0W4xjlG0Qu1x7mrZRqafH1dDH5aVC7 oZ2g== 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=CoN5bnAyEKCAWHSaWs6ibXtt8pvphyxr5HGG/4MTH2E=; b=zd9++IBvKKWb6UdrS8MxUlAacZI3MZXueuJjAvKK12w0G9/VJqEIHKTy47uM7NbMpk iyUVjeF/QXTaJk7xLmaJu1gpP5XjBWvb1HfrQthEtFP/Uj0jj+oKX2Ja1bVYcPJfpDUQ 5+e9pnBHQY7boPYJfYJEUt2O8Wzv/2d8kcbGpyoGB+4NtZQk6U9ul1YxFwgP9Wnetupv k9mWQ81tvSc6Mw7lDO73/vbdYWsmyQLy6/6qCt4AtJT/RqerHZvIN4/OVSLyRz4V0cRy Mdd7cDfsjC0n/8pPTw6f+/cb+G3eo/+L5X5dguy/SxGpdAWEmrzYnYjADCS+EEMfsLo2 +35Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="A3Y//RJ0"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id e18si65051eds.250.2020.06.01.11.11.46; Mon, 01 Jun 2020 11:12:09 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="A3Y//RJ0"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730773AbgFASIr (ORCPT + 99 others); Mon, 1 Jun 2020 14:08:47 -0400 Received: from mail.kernel.org ([198.145.29.99]:54956 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730764AbgFASIo (ORCPT ); Mon, 1 Jun 2020 14:08:44 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.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 75581207D0; Mon, 1 Jun 2020 18:08:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1591034923; bh=2ZPjej86uWTbLn4JuUOXaDIYjHQwrcYDh8zvLp7nqxA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=A3Y//RJ0zsqcugpTacUP6yvsXxnn5ZNLruvMSIF1lojkc0qZJzqiZlNv773deffp6 FhMpTYNTPx9KbcVzhlWx1e1aHEa1Ws1eUxZ06XOLenWgd4z9avDnkx6TvLi930jiGJ 7G7RFj2iTXk16G6g6inyONoWnscc273CuuSB4HRI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Tomas Paukrt , Russell King , Sasha Levin Subject: [PATCH 5.4 074/142] ARM: uaccess: fix DACR mismatch with nested exceptions Date: Mon, 1 Jun 2020 19:53:52 +0200 Message-Id: <20200601174045.466421674@linuxfoundation.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200601174037.904070960@linuxfoundation.org> References: <20200601174037.904070960@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: Russell King [ Upstream commit 71f8af1110101facfad68989ff91f88f8e2c3e22 ] Tomas Paukrt reports that his SAM9X60 based system (ARM926, ARMv5TJ) fails to fix up alignment faults, eventually resulting in a kernel oops. The problem occurs when using CONFIG_CPU_USE_DOMAINS with commit e6978e4bf181 ("ARM: save and reset the address limit when entering an exception"). This is because the address limit is set back to TASK_SIZE on exception entry, and, although it is restored on exception exit, the domain register is not. Hence, this sequence can occur: interrupt pt_regs->addr_limit = addr_limit // USER_DS addr_limit = USER_DS alignment exception __probe_kernel_read() old_fs = get_fs() // USER_DS set_fs(KERNEL_DS) addr_limit = KERNEL_DS dacr.kernel = DOMAIN_MANAGER interrupt pt_regs->addr_limit = addr_limit // KERNEL_DS addr_limit = USER_DS alignment exception __probe_kernel_read() old_fs = get_fs() // USER_DS set_fs(KERNEL_DS) addr_limit = KERNEL_DS dacr.kernel = DOMAIN_MANAGER ... set_fs(old_fs) addr_limit = USER_DS dacr.kernel = DOMAIN_CLIENT ... addr_limit = pt_regs->addr_limit // KERNEL_DS interrupt returns At this point, addr_limit is correctly restored to KERNEL_DS for __probe_kernel_read() to continue execution, but dacr.kernel is not, it has been reset by the set_fs(old_fs) to DOMAIN_CLIENT. This would not have happened prior to the mentioned commit, because addr_limit would remain KERNEL_DS, so get_fs() would have returned KERNEL_DS, and so would correctly nest. This commit fixes the problem by also saving the DACR on exception entry if either CONFIG_CPU_SW_DOMAIN_PAN or CONFIG_CPU_USE_DOMAINS are enabled, and resetting the DACR appropriately on exception entry to match addr_limit and PAN settings. Fixes: e6978e4bf181 ("ARM: save and reset the address limit when entering an exception") Reported-by: Tomas Paukrt Signed-off-by: Russell King Signed-off-by: Sasha Levin --- arch/arm/include/asm/uaccess-asm.h | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/arch/arm/include/asm/uaccess-asm.h b/arch/arm/include/asm/uaccess-asm.h index e46468b91eaa..907571fd05c6 100644 --- a/arch/arm/include/asm/uaccess-asm.h +++ b/arch/arm/include/asm/uaccess-asm.h @@ -67,15 +67,21 @@ #endif .endm -#ifdef CONFIG_CPU_SW_DOMAIN_PAN +#if defined(CONFIG_CPU_SW_DOMAIN_PAN) || defined(CONFIG_CPU_USE_DOMAINS) #define DACR(x...) x #else #define DACR(x...) #endif /* - * Save the address limit on entry to a privileged exception and - * if using PAN, save and disable usermode access. + * Save the address limit on entry to a privileged exception. + * + * If we are using the DACR for kernel access by the user accessors + * (CONFIG_CPU_USE_DOMAINS=y), always reset the DACR kernel domain + * back to client mode, whether or not \disable is set. + * + * If we are using SW PAN, set the DACR user domain to no access + * if \disable is set. */ .macro uaccess_entry, tsk, tmp0, tmp1, tmp2, disable ldr \tmp1, [\tsk, #TI_ADDR_LIMIT] @@ -84,8 +90,17 @@ DACR( mrc p15, 0, \tmp0, c3, c0, 0) DACR( str \tmp0, [sp, #SVC_DACR]) str \tmp1, [sp, #SVC_ADDR_LIMIT] - .if \disable - uaccess_disable \tmp0 + .if \disable && IS_ENABLED(CONFIG_CPU_SW_DOMAIN_PAN) + /* kernel=client, user=no access */ + mov \tmp2, #DACR_UACCESS_DISABLE + mcr p15, 0, \tmp2, c3, c0, 0 + instr_sync + .elseif IS_ENABLED(CONFIG_CPU_USE_DOMAINS) + /* kernel=client */ + bic \tmp2, \tmp0, #domain_mask(DOMAIN_KERNEL) + orr \tmp2, \tmp2, #domain_val(DOMAIN_KERNEL, DOMAIN_CLIENT) + mcr p15, 0, \tmp2, c3, c0, 0 + instr_sync .endif .endm -- 2.25.1