From patchwork Mon Sep 12 09:51:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 9326081 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 1AE4160839 for ; Mon, 12 Sep 2016 09:54:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0A6B528CC3 for ; Mon, 12 Sep 2016 09:54:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F2D1928CC5; Mon, 12 Sep 2016 09:54:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 212AC28CC3 for ; Mon, 12 Sep 2016 09:54:23 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bjNu5-0007pl-8v; Mon, 12 Sep 2016 09:51:53 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bjNu3-0007os-UA for xen-devel@lists.xen.org; Mon, 12 Sep 2016 09:51:52 +0000 Received: from [85.158.137.68] by server-5.bemta-3.messagelabs.com id 5B/E4-03281-7BA76D75; Mon, 12 Sep 2016 09:51:51 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupnkeJIrShJLcpLzFFi42JxWrohUndb1bV wg4nr9S2WfFzM4sDocXT3b6YAxijWzLyk/IoE1ozm8xNYCk6IVWz9d4qtgbFJqIuRk0NCwF/i 0v9vjCA2m4C+xO4Xn5hAbBEBdYnTHRdZuxg5OJgF/CQOPfAFCQsLeErcun+dHcRmEVCVmL5oF 1g5r4CHxLcPXxkhRspJnD/+kxnE5gSqX/d+OQuILQRUc+b6DlYIW03iWv8ldoheQYmTM5+A1T ALSEgcfPGCGWIOt8Tt01OZJzDyzUJSNgtJ2QJGplWM6sWpRWWpRbomeklFmekZJbmJmTm6hgb GermpxcWJ6ak5iUnFesn5uZsYgQHFAAQ7GBu/OB1ilORgUhLlTRK8Fi7El5SfUpmRWJwRX1Sa k1p8iFGGg0NJgre5EignWJSanlqRlpkDDG2YtAQHj5IIbzJImre4IDG3ODMdInWKUVFKnLcDJ CEAksgozYNrg8XTJUZZKWFeRqBDhHgKUotyM0tQ5V8xinMwKgnzGoNM4cnMK4Gb/gpoMRPQ4q dbL4MsLklESEk1MMqGHc56kVsqoLjHYNYq9W7+V6Hrec9vNpr2vdPzX9IFvYXn0qMTj90Um6i RNPX07aqCV3c3r1rrNX9K5k0zQ8sIoUuv3msmygl4BLjwPw0Kq/z6QkT70ve+Wwdez5TLqMqd qm/0b1PajPcSoem8Lqaq6d63Tm1Vf/Dhz3RNaZM7H0vY+i1TniqxFGckGmoxFxUnAgD78UbMo gIAAA== X-Env-Sender: prvs=0565cf92a=Andrew.Cooper3@citrix.com X-Msg-Ref: server-5.tower-31.messagelabs.com!1473673904!56962932!3 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 8.84; banners=-,-,- X-VirusChecked: Checked Received: (qmail 61374 invoked from network); 12 Sep 2016 09:51:50 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-5.tower-31.messagelabs.com with RC4-SHA encrypted SMTP; 12 Sep 2016 09:51:50 -0000 X-IronPort-AV: E=Sophos;i="5.30,322,1470700800"; d="scan'208";a="377658235" From: Andrew Cooper To: Xen-devel Date: Mon, 12 Sep 2016 10:51:38 +0100 Message-ID: <1473673900-8585-5-git-send-email-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1473673900-8585-1-git-send-email-andrew.cooper3@citrix.com> References: <1473673900-8585-1-git-send-email-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-DLP: MIA2 Cc: Andrew Cooper , Jan Beulich Subject: [Xen-devel] [PATCH 4/6] x86/xstate: Fix latent bugs in expand_xsave_states() X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Without checking the size input, the memcpy() for the uncompressed path might read off the end of the vcpu's xsave_area. Both callers pass the approprite size, so hold them to it with a BUG_ON(). The compressed path is currently dead code, but its attempt to avoid leaking uninitalised data was incomplete. The current xstate_bv will be less than xcr0_accum if some bits of xsave state are in their default values. Work around this by zeroing the whole rest of the buffer before decompression. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich --- xen/arch/x86/xstate.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c index 6e4a0d3..1973ba0 100644 --- a/xen/arch/x86/xstate.c +++ b/xen/arch/x86/xstate.c @@ -169,6 +169,17 @@ static void *get_xsave_addr(struct xsave_struct *xsave, (void *)xsave + comp_offsets[xfeature_idx] : NULL; } +/* + * Serialise a vcpus xsave state into a representation suitable for the + * toolstack. + * + * Internally a vcpus xsave state may be compressed or uncompressed, depending + * on the features in use, but the ABI with the toolstack is strictly + * uncompressed. + * + * It is the callers responsibility to ensure that there is xsave state to + * serialise, and that the provided buffer is exactly the right size. + */ void expand_xsave_states(struct vcpu *v, void *dest, unsigned int size) { struct xsave_struct *xsave = v->arch.xsave_area; @@ -176,6 +187,11 @@ void expand_xsave_states(struct vcpu *v, void *dest, unsigned int size) u64 xstate_bv = xsave->xsave_hdr.xstate_bv; u64 valid; + /* Check there is state to serialise (i.e. at least an XSAVE_HDR) */ + BUG_ON(!v->arch.xcr0_accum); + /* Check there is the correct room to decompress into. */ + BUG_ON(size != xstate_ctxt_size(v->arch.xcr0_accum)); + if ( !(xsave->xsave_hdr.xcomp_bv & XSTATE_COMPACTION_ENABLED) ) { memcpy(dest, xsave, size); @@ -189,6 +205,7 @@ void expand_xsave_states(struct vcpu *v, void *dest, unsigned int size) * Copy legacy XSAVE area and XSAVE hdr area. */ memcpy(dest, xsave, XSTATE_AREA_MIN_SIZE); + memset(dest + XSTATE_AREA_MIN_SIZE, 0, size - XSTATE_AREA_MIN_SIZE); ((struct xsave_struct *)dest)->xsave_hdr.xcomp_bv = 0; @@ -205,11 +222,9 @@ void expand_xsave_states(struct vcpu *v, void *dest, unsigned int size) if ( src ) { - ASSERT((xstate_offsets[index] + xstate_sizes[index]) <= size); + BUG_ON((xstate_offsets[index] + xstate_sizes[index]) <= size); memcpy(dest + xstate_offsets[index], src, xstate_sizes[index]); } - else - memset(dest + xstate_offsets[index], 0, xstate_sizes[index]); valid &= ~feature; }