Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp3914452imm; Mon, 8 Oct 2018 11:36:28 -0700 (PDT) X-Google-Smtp-Source: ACcGV62LUgf7dcX9Bk17ZAcg3wB25t1jERTmEbPaghjb09c/tlmvpEnyOl6IQUnPHw//+b21whzB X-Received: by 2002:aa7:8598:: with SMTP id w24-v6mr26792075pfn.77.1539023788376; Mon, 08 Oct 2018 11:36:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539023788; cv=none; d=google.com; s=arc-20160816; b=i9qborGq05CmQGF6q0/bzyCMAWMMKLhjH/Np2EBAfNegov8D2fjBabsH3LRqSJUEr6 IdbTOj1bfRlKAXRe+50RTWWgc95fqYlBay9faL4tfFOEvzKTjaH+MIupnYcxClnpxrBK O4gSYDl3v6bZGVpaWJEv6l61ZpHgvNT0fKYEo6z2GIPfXl7rWx+yiWrHNYzzI6XmGuT6 vFZPbsiqYrE1M1Q9kTPmmD/fZV52Isx6BPqTnq3wuScRepZQ6tJwHpEwE/Cn7uN2uI0K B59t3uJ+VFau9swEyLu7a7AHhdLgdmBAiPLZNeApril6oU8JYRDxOj56M9G+PWdglAOz Dxjw== 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=TUYTr8xCgIq/+1k/O4rlD/EkTu7IfOwRS9jagqjFlxc=; b=acoYQABM551UOeI7jOWowWSp6E2kuZ0K0UI9UsjpwxDJTSv4t333qRLWGhbstcSq9R 7iLHlmsRD0bHQQujgBeQtl5KLguU/VR2kWVa/9QYQd1hckK/r/qfgs9SRltD+fUZPpC5 c22E6VNU63M/wm4o3ZcbNBAqrgvK1y3glueFySmTHapDt5tnY0edMWgwXItvOCcU2p65 bioFpGvRIuTr1V5dzsxTlWtgIXDupqXJqHEg3HDM9DAxkKYoCbYIMk7j1tsj4rX/VTVd RoR2FpALPYv/aUivSNo/DGdH2+r6jBs5PFfBeVxLqZaMb1JBgBOSCzuS8nR6AJLSUUGc i1pQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=MYU0rXUP; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j7-v6si16362142pgj.532.2018.10.08.11.36.13; Mon, 08 Oct 2018 11:36:28 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=MYU0rXUP; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728217AbeJIBsY (ORCPT + 99 others); Mon, 8 Oct 2018 21:48:24 -0400 Received: from mail.kernel.org ([198.145.29.99]:60572 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726522AbeJIBsY (ORCPT ); Mon, 8 Oct 2018 21:48:24 -0400 Received: from localhost (ip-213-127-77-176.ip.prioritytelecom.net [213.127.77.176]) (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 8F7F42064A; Mon, 8 Oct 2018 18:35:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1539023721; bh=tisW1AGSdOL7jD+h/cHDjbs4Zb9EmGOaOlgYCUlI1xo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MYU0rXUPqtz2BBtwGOiCUa4yScqDlyBAfSDcyiMIbkFgaIB6OEGZ7VLaMq9WK59hM JKMsvt4J9kq9wQ2YUOS7C/bu13W/proP9jYWpV+UJxyKqHAbsQLcUIoe32P9OH4rYJ 32ocRtTpmSlsQGwb5Pu/dRRlgVHDS/DuYZpcAnzM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Christoffer Dall , Mark Rutland , Dave Martin , Marc Zyngier , Will Deacon Subject: [PATCH 4.4 062/113] arm64: KVM: Tighten guest core register access from userspace Date: Mon, 8 Oct 2018 20:31:03 +0200 Message-Id: <20181008175534.399469315@linuxfoundation.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181008175530.864641368@linuxfoundation.org> References: <20181008175530.864641368@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review 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 4.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Dave Martin commit d26c25a9d19b5976b319af528886f89cf455692d upstream. We currently allow userspace to access the core register file in about any possible way, including straddling multiple registers and doing unaligned accesses. This is not the expected use of the ABI, and nobody is actually using it that way. Let's tighten it by explicitly checking the size and alignment for each field of the register file. Cc: Fixes: 2f4a07c5f9fe ("arm64: KVM: guest one-reg interface") Reviewed-by: Christoffer Dall Reviewed-by: Mark Rutland Signed-off-by: Dave Martin [maz: rewrote Dave's initial patch to be more easily backported] Signed-off-by: Marc Zyngier Signed-off-by: Will Deacon Signed-off-by: Greg Kroah-Hartman --- arch/arm64/kvm/guest.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -48,6 +48,45 @@ static u64 core_reg_offset_from_id(u64 i return id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_CORE); } +static int validate_core_offset(const struct kvm_one_reg *reg) +{ + u64 off = core_reg_offset_from_id(reg->id); + int size; + + switch (off) { + case KVM_REG_ARM_CORE_REG(regs.regs[0]) ... + KVM_REG_ARM_CORE_REG(regs.regs[30]): + case KVM_REG_ARM_CORE_REG(regs.sp): + case KVM_REG_ARM_CORE_REG(regs.pc): + case KVM_REG_ARM_CORE_REG(regs.pstate): + case KVM_REG_ARM_CORE_REG(sp_el1): + case KVM_REG_ARM_CORE_REG(elr_el1): + case KVM_REG_ARM_CORE_REG(spsr[0]) ... + KVM_REG_ARM_CORE_REG(spsr[KVM_NR_SPSR - 1]): + size = sizeof(__u64); + break; + + case KVM_REG_ARM_CORE_REG(fp_regs.vregs[0]) ... + KVM_REG_ARM_CORE_REG(fp_regs.vregs[31]): + size = sizeof(__uint128_t); + break; + + case KVM_REG_ARM_CORE_REG(fp_regs.fpsr): + case KVM_REG_ARM_CORE_REG(fp_regs.fpcr): + size = sizeof(__u32); + break; + + default: + return -EINVAL; + } + + if (KVM_REG_SIZE(reg->id) == size && + IS_ALIGNED(off, size / sizeof(__u32))) + return 0; + + return -EINVAL; +} + static int get_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) { /* @@ -67,6 +106,9 @@ static int get_core_reg(struct kvm_vcpu (off + (KVM_REG_SIZE(reg->id) / sizeof(__u32))) >= nr_regs) return -ENOENT; + if (validate_core_offset(reg)) + return -EINVAL; + if (copy_to_user(uaddr, ((u32 *)regs) + off, KVM_REG_SIZE(reg->id))) return -EFAULT; @@ -89,6 +131,9 @@ static int set_core_reg(struct kvm_vcpu (off + (KVM_REG_SIZE(reg->id) / sizeof(__u32))) >= nr_regs) return -ENOENT; + if (validate_core_offset(reg)) + return -EINVAL; + if (KVM_REG_SIZE(reg->id) > sizeof(tmp)) return -EINVAL;