From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0CABF223326; Thu, 12 Dec 2024 16:37:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734021448; cv=none; b=mBLPqntJWXr7okI/xKgGq7xsBHi0luF3cDGvTr8aZ+AyI8+CA8tlNGEW6WQaX3RF9BE0nuaDWac41Zy0bMNbC3S3yJnb1hTFKeHqJwpuXjgbWSYdRNoXt8yr8cN1IGHLTaJi1NH/z5vqAUgAItfjlkJ9ro7SvVQ8/3spddUB2a8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734021448; c=relaxed/simple; bh=W5PqzKB9r91nohR/AP9QfDfVOA2xdwGM3WEjoE3fd9I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=p0Rw07ZuhfwLbcasz+ytdi8Us3Uf/ZJ4XFBsK+dupYWF4bAhbW6d671E6XAfs9wx/sG+kaVMsT77eJj8Tj7zFkFt09VUEL0ig5Rqq4uJzpphkrdYJBwmdx9f0kV/yGS6LO8EOspZGBvtVp2BJo5v4Y1EAAa1SGe+Gp8AF7PnadY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=16BjaJVs; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="16BjaJVs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1A6D0C4CECE; Thu, 12 Dec 2024 16:37:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1734021447; bh=W5PqzKB9r91nohR/AP9QfDfVOA2xdwGM3WEjoE3fd9I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=16BjaJVsB7/0xAVwFHoWwxiBah0e/28M9jA8V/XqXVNLBVkMgAAqhSfds0DV9/kJm lfUwpRcZ/ESjUrrbVwf5dyC4ueL4tmdG7zp3a70wHjBERz/65FFPihYQEgGAUAmMm+ y9Es4EH6VwvgY5CQzImABJyqSk8Z6vwr9QaPyQN8= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Kunkun Jiang , Jing Zhang , Oliver Upton Subject: [PATCH 6.1 739/772] KVM: arm64: vgic-its: Add a data length check in vgic_its_save_* Date: Thu, 12 Dec 2024 16:01:24 +0100 Message-ID: <20241212144420.465034061@linuxfoundation.org> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20241212144349.797589255@linuxfoundation.org> References: <20241212144349.797589255@linuxfoundation.org> User-Agent: quilt/0.67 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jing Zhang commit 7fe28d7e68f92cc3d0668b8f2fbdf5c303ac3022 upstream. In all the vgic_its_save_*() functinos, they do not check whether the data length is 8 bytes before calling vgic_write_guest_lock. This patch adds the check. To prevent the kernel from being blown up when the fault occurs, KVM_BUG_ON() is used. And the other BUG_ON()s are replaced together. Cc: stable@vger.kernel.org Signed-off-by: Kunkun Jiang [Jing: Update with the new entry read/write helpers] Signed-off-by: Jing Zhang Link: https://lore.kernel.org/r/20241107214137.428439-4-jingzhangos@google.com Signed-off-by: Oliver Upton Signed-off-by: Greg Kroah-Hartman --- arch/arm64/kvm/vgic/vgic-its.c | 20 ++++++++------------ arch/arm64/kvm/vgic/vgic.h | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 12 deletions(-) --- a/arch/arm64/kvm/vgic/vgic-its.c +++ b/arch/arm64/kvm/vgic/vgic-its.c @@ -2207,7 +2207,6 @@ static int scan_its_table(struct vgic_it static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev, struct its_ite *ite, gpa_t gpa, int ite_esz) { - struct kvm *kvm = its->dev->kvm; u32 next_offset; u64 val; @@ -2216,7 +2215,8 @@ static int vgic_its_save_ite(struct vgic ((u64)ite->irq->intid << KVM_ITS_ITE_PINTID_SHIFT) | ite->collection->collection_id; val = cpu_to_le64(val); - return kvm_write_guest_lock(kvm, gpa, &val, ite_esz); + + return vgic_its_write_entry_lock(its, gpa, val, ite_esz); } /** @@ -2357,7 +2357,6 @@ static int vgic_its_restore_itt(struct v static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev, gpa_t ptr, int dte_esz) { - struct kvm *kvm = its->dev->kvm; u64 val, itt_addr_field; u32 next_offset; @@ -2368,7 +2367,8 @@ static int vgic_its_save_dte(struct vgic (itt_addr_field << KVM_ITS_DTE_ITTADDR_SHIFT) | (dev->num_eventid_bits - 1)); val = cpu_to_le64(val); - return kvm_write_guest_lock(kvm, ptr, &val, dte_esz); + + return vgic_its_write_entry_lock(its, ptr, val, dte_esz); } /** @@ -2555,7 +2555,8 @@ static int vgic_its_save_cte(struct vgic ((u64)collection->target_addr << KVM_ITS_CTE_RDBASE_SHIFT) | collection->collection_id); val = cpu_to_le64(val); - return kvm_write_guest_lock(its->dev->kvm, gpa, &val, esz); + + return vgic_its_write_entry_lock(its, gpa, val, esz); } /* @@ -2571,8 +2572,7 @@ static int vgic_its_restore_cte(struct v u64 val; int ret; - BUG_ON(esz > sizeof(val)); - ret = kvm_read_guest_lock(kvm, gpa, &val, esz); + ret = vgic_its_read_entry_lock(its, gpa, &val, esz); if (ret) return ret; val = le64_to_cpu(val); @@ -2610,7 +2610,6 @@ static int vgic_its_save_collection_tabl u64 baser = its->baser_coll_table; gpa_t gpa = GITS_BASER_ADDR_48_to_52(baser); struct its_collection *collection; - u64 val; size_t max_size, filled = 0; int ret, cte_esz = abi->cte_esz; @@ -2634,10 +2633,7 @@ static int vgic_its_save_collection_tabl * table is not fully filled, add a last dummy element * with valid bit unset */ - val = 0; - BUG_ON(cte_esz > sizeof(val)); - ret = kvm_write_guest_lock(its->dev->kvm, gpa, &val, cte_esz); - return ret; + return vgic_its_write_entry_lock(its, gpa, 0, cte_esz); } /** --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -6,6 +6,7 @@ #define __KVM_ARM_VGIC_NEW_H__ #include +#include #define PRODUCT_ID_KVM 0x4b /* ASCII code K */ #define IMPLEMENTER_ARM 0x43b @@ -131,6 +132,29 @@ static inline bool vgic_irq_is_multi_sgi return vgic_irq_get_lr_count(irq) > 1; } +static inline int vgic_its_read_entry_lock(struct vgic_its *its, gpa_t eaddr, + u64 *eval, unsigned long esize) +{ + struct kvm *kvm = its->dev->kvm; + + if (KVM_BUG_ON(esize != sizeof(*eval), kvm)) + return -EINVAL; + + return kvm_read_guest_lock(kvm, eaddr, eval, esize); + +} + +static inline int vgic_its_write_entry_lock(struct vgic_its *its, gpa_t eaddr, + u64 eval, unsigned long esize) +{ + struct kvm *kvm = its->dev->kvm; + + if (KVM_BUG_ON(esize != sizeof(eval), kvm)) + return -EINVAL; + + return kvm_write_guest_lock(kvm, eaddr, &eval, esize); +} + /* * This struct provides an intermediate representation of the fields contained * in the GICH_VMCR and ICH_VMCR registers, such that code exporting the GIC