From patchwork Mon Jun 22 10:41:24 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhichao Huang X-Patchwork-Id: 50144 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wg0-f72.google.com (mail-wg0-f72.google.com [74.125.82.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 4932121575 for ; Mon, 22 Jun 2015 10:41:55 +0000 (UTC) Received: by wgfj7 with SMTP id j7sf40052974wgf.1 for ; Mon, 22 Jun 2015 03:41:54 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=dnFSk8JfCAMCZwqFWm2SqokfBy9/BSHRzX26afbhpBM=; b=JW4a4OEDT+/rr1EHFy1yD1x+w9ChaaUARai5Lur6uo0pWqhRcXhFqVx+jeKdCFjRms TkWROh+RGzTYz4SCiiBHcOthIZQ2qvns1wz9XRuB5VA8fx2GbS0QGRCaj3ISBYpkNpMS eW1PUckseR6/1geLNxBAHNfBRkepcalPiIyDre8OnlYX9wpAhvUizwjoMDjhAHYXIZR5 0/zYnDMvqbZZXiJCbuV30x/8MKlzu11BZ+KgvIMa6/1+1Dfum2+En69/xeNX7N6zbbKP SPyI2AwpJkpTPmga4PjAQ0NQvyKUf3KD0W1XaLPFlEK93xvOYOlBM4WgttwBTl/87g9e KODw== X-Gm-Message-State: ALoCoQlJxTbNX3RG8diFWqJoOJ+BdNVVAJbaeeeydhh2WKedwCyqXAp0zeWNKgyxtSmz8/l1iAXB X-Received: by 10.112.166.137 with SMTP id zg9mr27494818lbb.11.1434969714190; Mon, 22 Jun 2015 03:41:54 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.242.2 with SMTP id wm2ls538398lac.38.gmail; Mon, 22 Jun 2015 03:41:54 -0700 (PDT) X-Received: by 10.112.132.9 with SMTP id oq9mr401783lbb.26.1434969713971; Mon, 22 Jun 2015 03:41:53 -0700 (PDT) Received: from mail-la0-f43.google.com (mail-la0-f43.google.com. [209.85.215.43]) by mx.google.com with ESMTPS id ws3si16223431lbb.70.2015.06.22.03.41.53 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 22 Jun 2015 03:41:53 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.43 as permitted sender) client-ip=209.85.215.43; Received: by lacny3 with SMTP id ny3so106966475lac.3 for ; Mon, 22 Jun 2015 03:41:53 -0700 (PDT) X-Received: by 10.112.219.70 with SMTP id pm6mr28862151lbc.41.1434969713720; Mon, 22 Jun 2015 03:41:53 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.108.230 with SMTP id hn6csp2287472lbb; Mon, 22 Jun 2015 03:41:52 -0700 (PDT) X-Received: by 10.66.122.144 with SMTP id ls16mr49608122pab.47.1434969711449; Mon, 22 Jun 2015 03:41:51 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id hw3si29052132pac.107.2015.06.22.03.41.50; Mon, 22 Jun 2015 03:41:51 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754356AbbFVKlt (ORCPT + 2 others); Mon, 22 Jun 2015 06:41:49 -0400 Received: from mail-pa0-f50.google.com ([209.85.220.50]:36332 "EHLO mail-pa0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754212AbbFVKls (ORCPT ); Mon, 22 Jun 2015 06:41:48 -0400 Received: by paceq1 with SMTP id eq1so107069045pac.3 for ; Mon, 22 Jun 2015 03:41:47 -0700 (PDT) X-Received: by 10.70.90.232 with SMTP id bz8mr44581436pdb.120.1434969707480; Mon, 22 Jun 2015 03:41:47 -0700 (PDT) Received: from localhost ([104.207.83.42]) by mx.google.com with ESMTPSA id fk5sm14826160pab.40.2015.06.22.03.41.45 (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 22 Jun 2015 03:41:46 -0700 (PDT) From: Zhichao Huang To: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, christoffer.dall@linaro.org, marc.zyngier@arm.com, alex.bennee@linaro.org, will.deacon@arm.com Cc: huangzhichao@huawei.com, Zhichao Huang , Subject: [PATCH v3 01/11] KVM: arm: plug guest debug exploit Date: Mon, 22 Jun 2015 18:41:24 +0800 Message-Id: <1434969694-7432-2-git-send-email-zhichao.huang@linaro.org> X-Mailer: git-send-email 1.9.5.msysgit.1 In-Reply-To: <1434969694-7432-1-git-send-email-zhichao.huang@linaro.org> References: <1434969694-7432-1-git-send-email-zhichao.huang@linaro.org> Sender: stable-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: stable@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: zhichao.huang@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.43 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Hardware debugging in guests is not intercepted currently, it means that a malicious guest can bring down the entire machine by writing to the debug registers. This patch enable trapping of all debug registers, preventing the guests to access the debug registers. This patch also disable the debug mode(DBGDSCR) in the guest world all the time, preventing the guests to mess with the host state. However, it is a precursor for later patches which will need to do more to world switch debug states while necessary. Cc: Signed-off-by: Zhichao Huang --- arch/arm/include/asm/kvm_coproc.h | 3 +- arch/arm/kvm/coproc.c | 60 +++++++++++++++++++++++++++++++++++---- arch/arm/kvm/handle_exit.c | 4 +-- arch/arm/kvm/interrupts_head.S | 13 ++++++++- 4 files changed, 70 insertions(+), 10 deletions(-) diff --git a/arch/arm/include/asm/kvm_coproc.h b/arch/arm/include/asm/kvm_coproc.h index 4917c2f..e74ab0f 100644 --- a/arch/arm/include/asm/kvm_coproc.h +++ b/arch/arm/include/asm/kvm_coproc.h @@ -31,7 +31,8 @@ void kvm_register_target_coproc_table(struct kvm_coproc_target_table *table); int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp_0_13_access(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run); -int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run); +int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run); +int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run); diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c index f3d88dc..2e12760 100644 --- a/arch/arm/kvm/coproc.c +++ b/arch/arm/kvm/coproc.c @@ -91,12 +91,6 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run) return 1; } -int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run) -{ - kvm_inject_undefined(vcpu); - return 1; -} - static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r) { /* @@ -519,6 +513,60 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) return emulate_cp15(vcpu, ¶ms); } +/** + * kvm_handle_cp14_64 -- handles a mrrc/mcrr trap on a guest CP14 access + * @vcpu: The VCPU pointer + * @run: The kvm_run struct + */ +int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run) +{ + struct coproc_params params; + + params.CRn = (kvm_vcpu_get_hsr(vcpu) >> 1) & 0xf; + params.Rt1 = (kvm_vcpu_get_hsr(vcpu) >> 5) & 0xf; + params.is_write = ((kvm_vcpu_get_hsr(vcpu) & 1) == 0); + params.is_64bit = true; + + params.Op1 = (kvm_vcpu_get_hsr(vcpu) >> 16) & 0xf; + params.Op2 = 0; + params.Rt2 = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf; + params.CRm = 0; + + /* raz_wi */ + (void)pm_fake(vcpu, ¶ms, NULL); + + /* handled */ + kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); + return 1; +} + +/** + * kvm_handle_cp14_32 -- handles a mrc/mcr trap on a guest CP14 access + * @vcpu: The VCPU pointer + * @run: The kvm_run struct + */ +int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run) +{ + struct coproc_params params; + + params.CRm = (kvm_vcpu_get_hsr(vcpu) >> 1) & 0xf; + params.Rt1 = (kvm_vcpu_get_hsr(vcpu) >> 5) & 0xf; + params.is_write = ((kvm_vcpu_get_hsr(vcpu) & 1) == 0); + params.is_64bit = false; + + params.CRn = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf; + params.Op1 = (kvm_vcpu_get_hsr(vcpu) >> 14) & 0x7; + params.Op2 = (kvm_vcpu_get_hsr(vcpu) >> 17) & 0x7; + params.Rt2 = 0; + + /* raz_wi */ + (void)pm_fake(vcpu, ¶ms, NULL); + + /* handled */ + kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); + return 1; +} + /****************************************************************************** * Userspace API *****************************************************************************/ diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c index 95f12b2..357ad1b 100644 --- a/arch/arm/kvm/handle_exit.c +++ b/arch/arm/kvm/handle_exit.c @@ -104,9 +104,9 @@ static exit_handle_fn arm_exit_handlers[] = { [HSR_EC_WFI] = kvm_handle_wfx, [HSR_EC_CP15_32] = kvm_handle_cp15_32, [HSR_EC_CP15_64] = kvm_handle_cp15_64, - [HSR_EC_CP14_MR] = kvm_handle_cp14_access, + [HSR_EC_CP14_MR] = kvm_handle_cp14_32, [HSR_EC_CP14_LS] = kvm_handle_cp14_load_store, - [HSR_EC_CP14_64] = kvm_handle_cp14_access, + [HSR_EC_CP14_64] = kvm_handle_cp14_64, [HSR_EC_CP_0_13] = kvm_handle_cp_0_13_access, [HSR_EC_CP10_ID] = kvm_handle_cp10_id, [HSR_EC_SVC_HYP] = handle_svc_hyp, diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S index 35e4a3a..f85c447 100644 --- a/arch/arm/kvm/interrupts_head.S +++ b/arch/arm/kvm/interrupts_head.S @@ -97,6 +97,10 @@ vcpu .req r0 @ vcpu pointer always in r0 mrs r8, LR_fiq mrs r9, SPSR_fiq push {r2-r9} + + /* DBGDSCR reg */ + mrc p14, 0, r2, c0, c1, 0 + push {r2} .endm .macro pop_host_regs_mode mode @@ -111,6 +115,9 @@ vcpu .req r0 @ vcpu pointer always in r0 * Clobbers all registers, in all modes, except r0 and r1. */ .macro restore_host_regs + pop {r2} + mcr p14, 0, r2, c0, c2, 2 + pop {r2-r9} msr r8_fiq, r2 msr r9_fiq, r3 @@ -159,6 +166,10 @@ vcpu .req r0 @ vcpu pointer always in r0 * Clobbers *all* registers. */ .macro restore_guest_regs + /* reset DBGDSCR to disable debug mode */ + mov r2, #0 + mcr p14, 0, r2, c0, c2, 2 + restore_guest_regs_mode svc, #VCPU_SVC_REGS restore_guest_regs_mode abt, #VCPU_ABT_REGS restore_guest_regs_mode und, #VCPU_UND_REGS @@ -607,7 +618,7 @@ ARM_BE8(rev r6, r6 ) * (hardware reset value is 0) */ .macro set_hdcr operation mrc p15, 4, r2, c1, c1, 1 - ldr r3, =(HDCR_TPM|HDCR_TPMCR) + ldr r3, =(HDCR_TPM|HDCR_TPMCR|HDCR_TDRA|HDCR_TDOSA|HDCR_TDA) .if \operation == vmentry orr r2, r2, r3 @ Trap some perfmon accesses .else