From patchwork Fri Feb 2 14:19:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 126713 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp687214ljc; Fri, 2 Feb 2018 06:21:52 -0800 (PST) X-Google-Smtp-Source: AH8x2275O48b9Jw3UwmPkMzBbGYCVBtbb8DxNMFTXnqYXStQbl+yp1m4gfpRkfP8TaWmWBGuQyAf X-Received: by 10.36.74.194 with SMTP id k185mr43131304itb.23.1517581312793; Fri, 02 Feb 2018 06:21:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517581312; cv=none; d=google.com; s=arc-20160816; b=K8rpv4tSK/oz3ziv7KpxgwNx4iUhEXf4/aR5/hqWYlGjAIHfsFpxqih3yNYvH6LOrD XOkj5Fwtf6IL3k+pdjI42Zhr6uo3rUHisfeHFLnS1WzTFwxuNEbyXl0Y0btu6S5MyDha sn1UFZTNwD/xjRwn6kfUvwvgvu2uOXWUPcLqD8q3sMnPLiPARogwdSUF+na/RBJT+Ucy hTDxThHIN9Yysvk7y31LsEb+ZAp4ez5zPujLowwgkLdu7rCv79qItlikwKXOM6MwDZGS i22Wp2tB64bjdyBl5b5QLgwhQYCvmcfKlVCOoS7XknXwCyw1JgY8Gx9jBGFya8CtB2UB wspQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:cc:references:in-reply-to:message-id:date:to :from:dkim-signature:arc-authentication-results; bh=vf1loLQGDj5eepuk/oLF+JRefU8LybUUiB5iq8voKxI=; b=ICSGSC0HMEOZ1uhSVPNgWLtGtDtKnB2XSLu1SJNqR5ythA+4qJaUTzxf209aM+Q1NN 6dTz48D3XO514x3PlEDx0d5ohALQTIfxNRrQTYEilBjx2WtYl8laBV9hPonCcjDONXVP DWJb1RRpTE7pWVDEgd3K8dj6d9Zcx/B1hdModQnLyhYMC2nG/1nKPmC/+b77eBfgncSy G6geQu+IuR5poWWL/GUMDFMtO28S+3OuENmv27iZR72vX8O10vvJmhz7XI64qHDp8k3y u/sbfYunoU4CDHq03y/DEigMzFAeaLfQd6e2jigDAbBsnvhx5wFsPe+HK5/8LiggqNUM KntA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=eroJAb74; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id m65si1617993itg.145.2018.02.02.06.21.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 02 Feb 2018 06:21:52 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=eroJAb74; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ehcBj-00086B-7Z; Fri, 02 Feb 2018 14:19:35 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ehcBi-00085v-D5 for xen-devel@lists.xen.org; Fri, 02 Feb 2018 14:19:34 +0000 X-Inumbo-ID: 0be03bcc-0824-11e8-ba59-bc764e045a96 Received: from mail-wr0-x244.google.com (unknown [2a00:1450:400c:c0c::244]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id 0be03bcc-0824-11e8-ba59-bc764e045a96; Fri, 02 Feb 2018 15:19:15 +0100 (CET) Received: by mail-wr0-x244.google.com with SMTP id w50so22726508wrc.2 for ; Fri, 02 Feb 2018 06:19:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=PGaUt4vGU0nTKsdwYdN2EUn3sR8D/oH0Xplfrtp4Nic=; b=eroJAb74P5rY770zJ2BwZCp9FqoH1OQ/eR3ngMRc1B2miL5lbivlf6Fr2VtMG4fjUV AlR+n3i6Dm3mFZKIT/Wxymtwoyp3272V2xS045yNgQKKXVaZANanr6I3Yt2amU3LGLmI r+xsQTAGuYJewIw2DrYUlRcdrsBoWog9TYqRQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=PGaUt4vGU0nTKsdwYdN2EUn3sR8D/oH0Xplfrtp4Nic=; b=m2zNVmO06nAjMY6aRqi6nvbw2Y+jTNAtuiTLiQMtUSJIbk/1f5F0VxhOjI8ITDjKIW 0Wk/uevOhnyviKFfPZaCU+Kwo++zeYZZsVE7gk0SjU24L7nN3gOWNe/8E/pnelrrJHOt EtMwaxxNFszqNknHyKlDVPWv3Xx66gmmNiW6mhdppl2mDPc1zthKMJ1lX8QseZhGWe8z Zs9FB69+1Emr8wS/qXnq27FTzOrRXGEIIIWTGT6kBbdjlShUP9hbjtuzZfdrjs0m1aQ6 XY0WiISMhoQFkzc8krYGY2uMtvm8+684t2dFLthZFNPcsydjAoB1yF5FBQPzs2IPNT/G jX/g== X-Gm-Message-State: AKwxyteHT7xGoQkxV1tSbC0tguBgdUUjI/D20tx8SAzLJLvSSzU+wvra d0ovTJkH+7c3Fv8WjUtGvAsrHHvI5oM= X-Received: by 10.223.151.207 with SMTP id t15mr11155040wrb.223.1517581171139; Fri, 02 Feb 2018 06:19:31 -0800 (PST) Received: from e108454-lin.cambridge.arm.com ([2001:41d0:1:6c23::1]) by smtp.gmail.com with ESMTPSA id u79sm3057422wma.10.2018.02.02.06.19.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 02 Feb 2018 06:19:30 -0800 (PST) From: Julien Grall To: xen-devel@lists.xen.org Date: Fri, 2 Feb 2018 14:19:22 +0000 Message-Id: <20180202141925.19387-5-julien.grall@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180202141925.19387-1-julien.grall@linaro.org> References: <20180202141925.19387-1-julien.grall@linaro.org> Cc: sstabellini@kernel.org, Julien Grall , andre.przywara@linaro.org Subject: [Xen-devel] [PATCH v4 4/7] xen/arm32: Add skeleton to harden branch predictor aliasing attacks X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Aliasing attacked against CPU branch predictors can allow an attacker to redirect speculative control flow on some CPUs and potentially divulge information from one context to another. This patch adds initiatial skeleton code behind a new Kconfig option to enable implementation-specific mitigations against these attacks for CPUs that are affected. Most of mitigations will have to be applied when entering to the hypervisor from the guest context. Because the attack is against branch predictor, it is not possible to safely use branch instruction before the mitigation is applied. Therefore this has to be done in the vector entry before jump to the helper handling a given exception. However, on arm32, each vector contain a single instruction. This means that the hardened vector tables may rely on the state of registers that does not hold when in the hypervisor (e.g SP is 8 bytes aligned). Therefore hypervisor code running with guest vectors table should be minimized and always have IRQs and SErrors masked to reduce the risk to use them. This patch provides an infrastructure to switch vector tables before entering to the guest and when leaving it. Note that alternative could have been used, but older Xen (4.8 or earlier) doesn't have support. So avoid using alternative to ease backporting. This is part of XSA-254. Signed-off-by: Julien Grall --- Changes in v2: - Clarify the commit message --- xen/arch/arm/Kconfig | 3 +++ xen/arch/arm/arm32/entry.S | 41 ++++++++++++++++++++++++++++++++++++++++- xen/arch/arm/cpuerrata.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig index 06fd85cc77..2782ee6589 100644 --- a/xen/arch/arm/Kconfig +++ b/xen/arch/arm/Kconfig @@ -191,6 +191,9 @@ config HARDEN_BRANCH_PREDICTOR config ARM64_HARDEN_BRANCH_PREDICTOR def_bool y if ARM_64 && HARDEN_BRANCH_PREDICTOR +config ARM32_HARDEN_BRANCH_PREDICTOR + def_bool y if ARM_32 && HARDEN_BRANCH_PREDICTOR + source "common/Kconfig" source "drivers/Kconfig" diff --git a/xen/arch/arm/arm32/entry.S b/xen/arch/arm/arm32/entry.S index 64876c1184..828e52c25c 100644 --- a/xen/arch/arm/arm32/entry.S +++ b/xen/arch/arm/arm32/entry.S @@ -34,6 +34,20 @@ blne save_guest_regs save_guest_regs: +#ifdef CONFIG_ARM32_HARDEN_BRANCH_PREDICTOR + /* + * Restore vectors table to the default as it may have been + * changed when returning to the guest (see + * return_to_hypervisor). We need to do that early (e.g before + * any interrupts are unmasked) because hardened vectors requires + * SP to be 8 bytes aligned. This does not hold when running in + * the hypervisor. + */ + ldr r1, =hyp_traps_vector + mcr p15, 4, r1, c12, c0, 0 + isb +#endif + ldr r11, =0xffffffff /* Clobber SP which is only valid for hypervisor frames. */ str r11, [sp, #UREGS_sp] SAVE_ONE_BANKED(SP_usr) @@ -179,12 +193,37 @@ return_to_guest: RESTORE_ONE_BANKED(R11_fiq); RESTORE_ONE_BANKED(R12_fiq); /* Fall thru */ return_to_hypervisor: - cpsid i + cpsid ai ldr lr, [sp, #UREGS_lr] ldr r11, [sp, #UREGS_pc] msr ELR_hyp, r11 ldr r11, [sp, #UREGS_cpsr] msr SPSR_hyp, r11 +#ifdef CONFIG_ARM32_HARDEN_BRANCH_PREDICTOR + /* + * Hardening branch predictor may require to setup a different + * vector tables before returning to the guests. Those vectors + * may rely on the state of registers that does not hold when + * running in the hypervisor (e.g SP is 8 bytes aligned). So setup + * HVBAR very late. + * + * Default vectors table will be restored on exit (see + * save_guest_regs). + */ + mov r9, #0 /* vector tables = NULL */ + /* + * Load vector tables pointer from the per-cpu bp_harden_vecs + * when returning to the guest only. + */ + and r11, #PSR_MODE_MASK + cmp r11, #PSR_MODE_HYP + ldrne r11, =per_cpu__bp_harden_vecs + mrcne p15, 4, r10, c13, c0, 2 /* r10 = per-cpu offset (HTPIDR) */ + addne r11, r11, r10 /* r11 = offset of the vector tables */ + ldrne r9, [r11] /* r9 = vector tables */ + cmp r9, #0 /* Only update HVBAR when the vector */ + mcrne p15, 4, r9, c12, c0, 0 /* tables is not NULL. */ +#endif pop {r0-r12} add sp, #(UREGS_SP_usr - UREGS_sp); /* SP, LR, SPSR, PC */ clrex diff --git a/xen/arch/arm/cpuerrata.c b/xen/arch/arm/cpuerrata.c index f1ea7f3c5b..0a138fa735 100644 --- a/xen/arch/arm/cpuerrata.c +++ b/xen/arch/arm/cpuerrata.c @@ -170,6 +170,36 @@ static int enable_psci_bp_hardening(void *data) #endif /* CONFIG_ARM64_HARDEN_BRANCH_PREDICTOR */ +/* Hardening Branch predictor code for Arm32 */ +#ifdef CONFIG_ARM32_HARDEN_BRANCH_PREDICTOR + +/* + * Per-CPU vector tables to use when returning to the guests. They will + * only be used on platform requiring to harden the branch predictor. + */ +DEFINE_PER_CPU_READ_MOSTLY(const char *, bp_harden_vecs); + +extern char hyp_traps_vector_bp_inv[]; + +static void __maybe_unused +install_bp_hardening_vecs(const struct arm_cpu_capabilities *entry, + const char *hyp_vecs, const char *desc) +{ + /* + * Enable callbacks are called on every CPU based on the + * capabilities. So double-check whether the CPU matches the + * entry. + */ + if ( !entry->matches(entry) ) + return; + + printk(XENLOG_INFO "CPU%u will %s on guest exit\n", + smp_processor_id(), desc); + this_cpu(bp_harden_vecs) = hyp_vecs; +} + +#endif + #define MIDR_RANGE(model, min, max) \ .matches = is_affected_midr_range, \ .midr_model = model, \