From patchwork Wed Jul 22 13:15:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Will Deacon X-Patchwork-Id: 11678471 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0202A913 for ; Wed, 22 Jul 2020 13:17:01 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CE2A02065F for ; Wed, 22 Jul 2020 13:17:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="1c+YJfsc"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="H/6pyqqq" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CE2A02065F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version: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=DUfs0/Frt7yMoIQEnq38Wjr1tfVWjWnI3bnGnwEs83E=; b=1c+YJfsc90qAAZxandaEoKz2ZU mdNF90iPLWKUXzCRhGh4kGbI4qIOH2vf3sOYYp2lMBMjxe87XZ5Qiwx1Csg3ku+cec1Sik5tJX0YE yUW/9qlFUOEJZcArexsKfWX1Y1IxsZ314sKlA2YAvQJ3hQrSOMgc4tg+tHBRxJRbtPumkv5aAzmyf 6ojL99rRms1yKiUAASdL0kVSaLXKOUg4poHAMifi9kxzD8qjH+f44NG3D7vW6bfNup4zn73Ja1mda q/Qa7Oat5IUTtK96R+nZXEXe+3DBoQJ/LH5rIXhtrl8yfCO1jt/e7lJlw40mH3pGxLkEqdYati6aV drBIs6+A==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jyEam-0003sW-Rk; Wed, 22 Jul 2020 13:15:28 +0000 Received: from mail.kernel.org ([198.145.29.99]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jyEak-0003s3-J2 for linux-arm-kernel@lists.infradead.org; Wed, 22 Jul 2020 13:15:27 +0000 Received: from localhost.localdomain (236.31.169.217.in-addr.arpa [217.169.31.236]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 789AD2065F; Wed, 22 Jul 2020 13:15:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1595423725; bh=309SgFrYGECpYvDHgcro6cdfQgAxAGKwgUlh3qTsjuA=; h=From:To:Cc:Subject:Date:From; b=H/6pyqqqhPSmMeEE5/uBBZbKv3zqe9HKg+3ZBp1wkHglSljjD1nGHr9OgaQUXAc8h Q2XstCynrehvAXFE4B6wZBaKriNhpKPLp1h5n0rYldwxs3eMi8ERjl+7ZZJTZLBELM nqeNbcTzDJJD4NKvzrk33LnRr69tm9k+z2ihy5fw= From: Will Deacon To: kvmarm@lists.cs.columbia.edu Subject: [PATCH] KVM: arm64: Don't inherit exec permission across page-table levels Date: Wed, 22 Jul 2020 14:15:10 +0100 Message-Id: <20200722131511.14639-1-will@kernel.org> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200722_091526_709416_6F1B9BB6 X-CRM114-Status: GOOD ( 12.58 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Will Deacon , suzuki.poulose@arm.com, Marc Zyngier , Quentin Perret , stable@vger.kernel.org, james.morse@arm.com, kernel-team@android.com, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org If a stage-2 page-table contains an executable, read-only mapping at the pte level (e.g. due to dirty logging being enabled), a subsequent write fault to the same page which tries to install a larger block mapping (e.g. due to dirty logging having been disabled) will erroneously inherit the exec permission and consequently skip I-cache invalidation for the rest of the block. Ensure that exec permission is only inherited by write faults when the new mapping is of the same size as the existing one. A subsequent instruction abort will result in I-cache invalidation for the entire block mapping. Cc: Marc Zyngier Cc: Quentin Perret Cc: Signed-off-by: Will Deacon Reviewed-by: Quentin Perret Tested-by: Quentin Perret --- Found by code inspection, rather than something actually going wrong. arch/arm64/kvm/mmu.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 8c0035cab6b6..69dc36d1d486 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -1326,7 +1326,7 @@ static bool stage2_get_leaf_entry(struct kvm *kvm, phys_addr_t addr, return true; } -static bool stage2_is_exec(struct kvm *kvm, phys_addr_t addr) +static bool stage2_is_exec(struct kvm *kvm, phys_addr_t addr, unsigned long sz) { pud_t *pudp; pmd_t *pmdp; @@ -1338,9 +1338,9 @@ static bool stage2_is_exec(struct kvm *kvm, phys_addr_t addr) return false; if (pudp) - return kvm_s2pud_exec(pudp); + return sz == PUD_SIZE && kvm_s2pud_exec(pudp); else if (pmdp) - return kvm_s2pmd_exec(pmdp); + return sz == PMD_SIZE && kvm_s2pmd_exec(pmdp); else return kvm_s2pte_exec(ptep); } @@ -1958,7 +1958,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, * execute permissions, and we preserve whatever we have. */ needs_exec = exec_fault || - (fault_status == FSC_PERM && stage2_is_exec(kvm, fault_ipa)); + (fault_status == FSC_PERM && + stage2_is_exec(kvm, fault_ipa, vma_pagesize)); if (vma_pagesize == PUD_SIZE) { pud_t new_pud = kvm_pfn_pud(pfn, mem_type);