From: Oliver Upton <oliver.upton@linux.dev>
To: Jing Zhang <jingzhangos@google.com>
Cc: stable@vger.kernel.org, Marc Zyngier <maz@kernel.org>,
Kunkun Jiang <jiangkunkun@huawei.com>
Subject: Re: [PATCH 5.15.y 1/3] KVM: arm64: vgic-its: Add a data length check in vgic_its_save_*
Date: Thu, 5 Dec 2024 16:48:44 -0800 [thread overview]
Message-ID: <Z1JJ7JDq3Ncily9z@linux.dev> (raw)
In-Reply-To: <20241204202340.2717420-1-jingzhangos@google.com>
On Wed, Dec 04, 2024 at 12:23:38PM -0800, Jing Zhang wrote:
> 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 <jiangkunkun@huawei.com>
> [Jing: Update with the new entry read/write helpers]
> Signed-off-by: Jing Zhang <jingzhangos@google.com>
> Link: https://lore.kernel.org/r/20241107214137.428439-4-jingzhangos@google.com
> Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
For the series:
Acked-by: Oliver Upton <oliver.upton@linux.dev>
--
Thanks,
Oliver
> ---
> arch/arm64/kvm/vgic/vgic-its.c | 20 ++++++++------------
> arch/arm64/kvm/vgic/vgic.h | 24 ++++++++++++++++++++++++
> 2 files changed, 32 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
> index 02ab6ab6ba91..bff7c49dfda5 100644
> --- a/arch/arm64/kvm/vgic/vgic-its.c
> +++ b/arch/arm64/kvm/vgic/vgic-its.c
> @@ -2135,7 +2135,6 @@ static int scan_its_table(struct vgic_its *its, gpa_t base, int size, u32 esz,
> 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;
>
> @@ -2144,7 +2143,8 @@ static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev,
> ((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);
> }
>
> /**
> @@ -2280,7 +2280,6 @@ static int vgic_its_restore_itt(struct vgic_its *its, struct its_device *dev)
> 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;
>
> @@ -2291,7 +2290,8 @@ static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev,
> (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);
> }
>
> /**
> @@ -2471,7 +2471,8 @@ static int vgic_its_save_cte(struct vgic_its *its,
> ((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);
> }
>
> static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa, int esz)
> @@ -2482,8 +2483,7 @@ static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa, int esz)
> 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);
> @@ -2517,7 +2517,6 @@ static int vgic_its_save_collection_table(struct vgic_its *its)
> 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;
>
> @@ -2541,10 +2540,7 @@ static int vgic_its_save_collection_table(struct vgic_its *its)
> * 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);
> }
>
> /**
> diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
> index 2be4b0759f5b..d2fc5ecb223e 100644
> --- 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 <linux/irqchip/arm-gic-common.h>
> +#include <asm/kvm_mmu.h>
>
> #define PRODUCT_ID_KVM 0x4b /* ASCII code K */
> #define IMPLEMENTER_ARM 0x43b
> @@ -126,6 +127,29 @@ static inline bool vgic_irq_is_multi_sgi(struct vgic_irq *irq)
> 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
>
> base-commit: 0a51d2d4527b43c5e467ffa6897deefeaf499358
> --
> 2.47.0.338.g60cca15819-goog
>
prev parent reply other threads:[~2024-12-06 0:48 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-04 20:23 [PATCH 5.15.y 1/3] KVM: arm64: vgic-its: Add a data length check in vgic_its_save_* Jing Zhang
2024-12-04 20:23 ` [PATCH 5.15.y 2/3] KVM: arm64: vgic-its: Clear DTE when MAPD unmaps a device Jing Zhang
2024-12-04 22:11 ` Sasha Levin
2024-12-04 20:23 ` [PATCH 5.15.y 3/3] KVM: arm64: vgic-its: Clear ITE when DISCARD frees an ITE Jing Zhang
2024-12-04 22:11 ` Sasha Levin
2024-12-04 22:12 ` [PATCH 5.15.y 1/3] KVM: arm64: vgic-its: Add a data length check in vgic_its_save_* Sasha Levin
2024-12-06 0:48 ` Oliver Upton [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Z1JJ7JDq3Ncily9z@linux.dev \
--to=oliver.upton@linux.dev \
--cc=jiangkunkun@huawei.com \
--cc=jingzhangos@google.com \
--cc=maz@kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox