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 EED22145A05; Fri, 6 Dec 2024 15:17:11 +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=1733498232; cv=none; b=Lo1Sjwbd8ULPgBUd6/JGJEV9Va7C9L2B7Ib2/gxyrF9PgIy/eL75kM9VUJrH9WSZIhwJHumaMHpp8nGNQ5+XbVUvWZgNWJhwopu5pTthgREwtbKw+K2/TrsBT+q2ZZPP5Bw1/YTA3mwftp6A11OlgwxE0oWV7JqyihB8XCN+Sys= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733498232; c=relaxed/simple; bh=MFr8n9+1W2ZzvJiF7CG2y9lRlzgcrr5qx4hlZx7ZzAU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PbXM5peuW+E5cvgv+GD0BRQ1lw7Ml4BJlDgkM6Z83ocEmpmqqXl0bfMzlFyGJ3tWynO0aY8Juh7TnZkF+YuhI9xXdrKT5IuXkMJhcV0HztlE7MXAC5sFS1eUHr5bO74GV7Zju9rUq2umcuenwEKRE+Mq7HWx5QcN24ugmqSqrAI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=IWo6IhYJ; 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="IWo6IhYJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0F120C4CED1; Fri, 6 Dec 2024 15:17:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1733498231; bh=MFr8n9+1W2ZzvJiF7CG2y9lRlzgcrr5qx4hlZx7ZzAU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IWo6IhYJW60ixHJcMHxjEkaF2pAPZy3NojFRbvrOijW7iZtpR4IpD4SUklsGcepkX fTj4B5ocLGDcVHz44ksahgMjE53TGpcSWPzSTp1QHRXDK9YXAEjzz+pw0MseWbloPd A/wX70bwF8NieAzs9ISHGIApLuxV53uDsdfBUpYY= 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.6 482/676] KVM: arm64: vgic-its: Add a data length check in vgic_its_save_* Date: Fri, 6 Dec 2024 15:35:01 +0100 Message-ID: <20241206143712.189670215@linuxfoundation.org> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20241206143653.344873888@linuxfoundation.org> References: <20241206143653.344873888@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.6-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 | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 12 deletions(-) --- a/arch/arm64/kvm/vgic/vgic-its.c +++ b/arch/arm64/kvm/vgic/vgic-its.c @@ -2211,7 +2211,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; @@ -2220,7 +2219,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 vgic_write_guest_lock(kvm, gpa, &val, ite_esz); + + return vgic_its_write_entry_lock(its, gpa, val, ite_esz); } /** @@ -2361,7 +2361,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; @@ -2372,7 +2371,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 vgic_write_guest_lock(kvm, ptr, &val, dte_esz); + + return vgic_its_write_entry_lock(its, ptr, val, dte_esz); } /** @@ -2559,7 +2559,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 vgic_write_guest_lock(its->dev->kvm, gpa, &val, esz); + + return vgic_its_write_entry_lock(its, gpa, val, esz); } /* @@ -2575,8 +2576,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); @@ -2614,7 +2614,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; @@ -2638,10 +2637,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 = vgic_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 @@ -145,6 +145,29 @@ static inline int vgic_write_guest_lock( return ret; } +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 vgic_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