Skip to content

[LTS 9.2] KVM: arm64: vgic-its: Avoid potential UAF in LPI translation cache #454

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: ciqlts9_2
Choose a base branch
from

Conversation

pvts-mat
Copy link
Contributor

@pvts-mat pvts-mat commented Jul 30, 2025

[LTS 9.2]
CVE-2024-26598
VULN-8190

Problem

https://access.redhat.com/security/cve/CVE-2024-26598

A flaw was found in the Linux kernel pertaining to a potential use-after-free (UAF) scenario in a system involving Logical Partitioning Interrupts (LPI) translation cache operations. Specifically, the issue arises when a cache hit occurs concurrently with an operation that invalidates the cache, such as a DISCARD ITS command. The root cause is traced to vgic_its_check_cache() not appropriately managing the reference count of the vgic_irq object. Upon returning from this function, the reference count of vgic_irq is not incremented. This issue can lead to the object being prematurely freed while still in use by other parts of the system, potentially resulting in undefined behavior or system instability.

Applicability: yes

No clear "fixes" commit provided in the mainline fix ad362fe to check ciqlts9_2's history for, but the applicability of the bug is highly likely, given that:

  1. The patch was applied to ciqlts9_4 by RH in 97e30cd.

  2. The patch was also applied to Linux stable 5.15 in 12c2759.

  3. The affected file arch/arm64/kvm/vgic/vgic-its.c barely differs between ciqlts9_4, ciqlts9_2 and linux-5.15.y. Compare the history (this is around 30% of its history, with the additional 106 commits of this file under previous path virt/kvm/arm/vgic/vgic-its.c shared one-to-one between all versions):

      kernel-mainline                                                                                ciqlts9_4               linux-5.15.y            ciqlts9_2              
      ---------------------------------------------------------------------------------------------  ----------------------  ----------------------  ---------------------- 
      fc4dafe87 2025-05-30 KVM: arm64: Protect vLPI translation with vgic_irq::irq_lock
      b586c5d21 2025-05-27 KVM: arm64: use kvm_trylock_all_vcpus when locking all vCPUs
      30deb51a6 2025-05-19 KVM: arm64: vgic-its: Add debugfs interface to expose ITS tables
      be7e61127 2024-12-03 KVM: arm64: vgic-its: Add error handling in vgic_its_cache_translation
      3b2c81d5f 2024-11-20 KVM: arm64: vgic-its: Add stronger type-checking to the ITS entry sizes
      add570b39 2024-11-20 KVM: arm64: vgic: Make vgic_get_irq() more robust
      7602ffd1d 2024-11-11 KVM: arm64: vgic-its: Clear ITE when DISCARD frees an ITE                                         ~ a0e0f67f2 2024-12-14
      e9649129d 2024-11-11 KVM: arm64: vgic-its: Clear DTE when MAPD unmaps a device                                         ~ fd92260b7 2024-12-14
      7fe28d7e6 2024-11-11 KVM: arm64: vgic-its: Add a data length check in vgic_its_save_*                                  ~ 065e075d4 2024-12-14
      0aa34b37a 2024-08-02 KVM: arm64: fix kdoc warnings in W=1 builds
      481c9ee84 2024-04-25 KVM: arm64: vgic-its: Get rid of the lpi_list_lock
      ec39bbfd5 2024-04-25 KVM: arm64: vgic-its: Rip out the global translation cache
      e64f2918c 2024-04-25 KVM: arm64: vgic-its: Use the per-ITS translation cache for injection
      dedfcd17f 2024-04-25 KVM: arm64: vgic-its: Spin off helper for finding ITS by doorbell addr
      8201d1028 2024-04-25 KVM: arm64: vgic-its: Maintain a translation cache per ITS
      c09c8ab99 2024-04-25 KVM: arm64: vgic-its: Scope translation cache invalidations to an ITS
      30a0ce9c4 2024-04-25 KVM: arm64: vgic-its: Get rid of vgic_copy_lpi_list()
      85d3ccc8b 2024-04-25 KVM: arm64: vgic-debug: Use an xarray mark for debug iterator
      11f4f8f3e 2024-04-25 KVM: arm64: vgic-its: Walk LPI xarray in vgic_its_cmd_handle_movall()
      c64115c80 2024-04-25 KVM: arm64: vgic-its: Walk LPI xarray in vgic_its_invall()
      720f73b75 2024-04-25 KVM: arm64: vgic-its: Walk LPI xarray in its_sync_lpi_pending_table()
      75841d89f 2024-02-24 KVM: arm64: Fix typos
      e27f2d561 2024-02-23 KVM: arm64: vgic: Don't acquire the lpi_list_lock in vgic_put_irq()
      50ac89bb7 2024-02-23 KVM: arm64: vgic: Ensure the irq refcount is nonzero when taking a ref
      05f4d4f5d 2024-02-23 KVM: arm64: vgic: Use atomics to count LPIs
      9880835af 2024-02-23 KVM: arm64: vgic: Get rid of the LPI linked-list
      2798683b8 2024-02-23 KVM: arm64: vgic-its: Walk the LPI xarray in vgic_copy_lpi_list()
      1d6f83f60 2024-02-23 KVM: arm64: vgic: Store LPIs in an xarray
      85a71ee9a 2024-02-21 KVM: arm64: vgic-its: Test for valid IRQ in MOVALL handler                ~ 7db7e58b4 2024-09-12  ~ 4deb8413e 2024-03-01
      8d3a7dfb8 2024-02-21 KVM: arm64: vgic-its: Test for valid IRQ in its_sync_lpi_pending_table()  ~ 492f7c66f 2024-09-12  ~ d81e2dc20 2024-03-01
      f779d2c01 2024-02-01 KVM: arm64: vgic-its: fix kernel-doc warnings
    > ad362fe07 2024-01-04 KVM: arm64: vgic-its: Avoid potential UAF in LPI translation cache        ~ 97e30cdb0 2024-02-07  ~ 12c2759ab 2024-01-25
      d455d366c 2023-09-30 KVM: arm64: vgic-its: Treat the collection target address as a vcpu_id    ~ 3a17399c2 2024-01-02
      9cf2f840c 2023-05-19 KVM: arm64: vgic: Wrap vgic_its_create() with config_lock                 ~ 9ea9abead 2023-07-03
      49e5d16b6 2023-04-12 KVM: arm64: vgic: Don't acquire its_lock before config_lock               ~ 0c82787ba 2023-07-03
      f00327731 2023-03-29 KVM: arm64: Use config_lock to protect vgic state                         ~ 2a4abe502 2023-07-03
      a23eaf936 2023-01-29 KVM: arm64: Add helper vgic_write_guest_lock()                            ~ 14274d6cd 2023-07-03
      9cb1096f8 2022-11-10 KVM: arm64: Enable ring-based dirty memory tracking                       ~ 7cde1e623 2023-07-03
      c000a2607 2022-10-15 KVM: arm64: vgic: Fix exit condition in scan_its_table()                  ~ a4e21f27c 2023-01-31  ~ 1e4e71f9e 2022-10-29  ~ a4e21f27c 2023-01-31
      096560dd1 2022-09-26 KVM: arm64: vgic: Remove duplicate check in update_affinity_collection()  ~ af5203e1c 2023-05-04
      8c5e74c90 2022-05-16 KVM: arm64: vgic: Undo work in failed ITS restores                        ~ 2d571ab1a 2023-01-31                          ~ 2d571ab1a 2023-01-31
      a1ccfd6f6 2022-05-16 KVM: arm64: vgic: Do not ignore vgic_its_restore_cte failures             ~ e7b743f9c 2023-01-31                          ~ e7b743f9c 2023-01-31
      243b1f6c8 2022-05-16 KVM: arm64: vgic: Add more checks when restoring ITS tables               ~ c9ed596a6 2023-01-31                          ~ c9ed596a6 2023-01-31
      cafe7e544 2022-05-16 KVM: arm64: vgic: Check that new ITEs could be saved in guest memory      ~ 83a3a8cef 2023-01-31                          ~ 83a3a8cef 2023-01-31
      4645d11f4 2022-05-04 KVM: arm64: vgic-v3: Implement MMIO-based LPI invalidation                ~ 2dcf0b0e1 2023-01-31                          ~ 2dcf0b0e1 2023-01-31
      94828468a 2022-05-04 KVM: arm64: vgic-v3: Expose GICR_CTLR.RWP when disabling LPIs             ~ d670f064e 2023-01-31                          ~ d670f064e 2023-01-31
      c707663e8 2022-04-06 KVM: arm64: vgic: Remove unnecessary type castings                        ~ 61c7d9002 2022-07-05                          ~ 61c7d9002 2022-07-05
      3ef231670 2021-10-17 KVM: arm64: vgic: Add memcg accounting to vgic allocations                ~ 5b2346c71 2022-07-05                          ~ 5b2346c71 2022-07-05
      2ec02f6c6 2021-10-11 KVM: arm64: vgic-v3: Check ITS region is not above the VM IPA size        ~ 444148ed1 2022-01-17                          ~ 444148ed1 2022-01-17
      4f0f586bf 2021-04-08 treewide: Change list_sort to use const pointers                          = 4f0f586bf 2021-04-08  = 4f0f586bf 2021-04-08  = 4f0f586bf 2021-04-08
      8082d50f4 2021-03-24 KVM: arm64: GICv4.1: Give a chance to save VLPI state                     = 8082d50f4 2021-03-24  = 8082d50f4 2021-03-24  = 8082d50f4 2021-03-24
      a47dee551 2020-07-05 KVM: arm64: Allow in-atomic injection of SPIs                             = a47dee551 2020-07-05  = a47dee551 2020-07-05  = a47dee551 2020-07-05 
      9ed24f4b7 2020-05-16 KVM: arm64: Move virt/kvm/arm to arch/arm64                               = 9ed24f4b7 2020-05-16  = 9ed24f4b7 2020-05-16  = 9ed24f4b7 2020-05-16
    
  4. The racing "DISCARD command" mentioned in the mainline's fix ad362fe message can be found in ciqlts9_2's version of the arch/arm64/kvm/vgic/vgic-its.c file

    /*
    * The DISCARD command frees an Interrupt Translation Table Entry (ITTE).
    * Must be called with the its_lock mutex held.
    */
    static int vgic_its_cmd_handle_discard(struct kvm *kvm, struct vgic_its *its,

These arguments are heuristic, but fully understanding the potential UAF scenario described in the bug and checking ciqlts9_2's code against it would be prohibitively time consuming.

Solution

The mainline fix ad362fe applies without any changes.

kABI check: passed

DEBUG=1 CVE=CVE-2024-26598 ./ninja.sh _kabi_checked__aarch64--test--ciqlts9_2-CVE-2024-26598

[0/1] Check ABI of kernel [ciqlts9_2-CVE-2024-26598]
++ uname -m
+ python3 /home/pvts/ctrliq-github/kernel-dist-git-el-9.2/SOURCES/check-kabi -k /home/pvts/ctrliq-github/kernel-dist-git-el-9.2/SOURCES/Module.kabi_aarch64 -s vms/aarch64--build--ciqlts9_2/build_files/kernel-src-tree-ciqlts9_2-CVE-2024-26598/Module.symvers
kABI check passed
+ touch state/kernels/ciqlts9_2-CVE-2024-26598/aarch64/kabi_checked

Boot test: passed

boot-test.log

Kselftests: passed relative

The tests were run in a KVM-based VM on a WHLE board with the Layerscape LS1046 microprocessor based on Arm Cortex-A721.

Unfortunately the most interesting kvm:* tests relating to the modified module couldn't be launched, as that required support for nested virtualization, which for the arm64 architecture was introduced in the ARMv8.3 revision2, while Cortex-A72 is ARMv83, 4. The kernel reports

[    4.718212] kvm [1]: HYP mode not available

during boot up and the kvm:* selftests complain about /dev/kvm not being available.

The test runs are split into two batches because of the net/forwarding:tc_police.sh test hanging the machine and interrupting the first batch prematurely.

Coverage

Including the omitted tests

bpf (except test_kmod.sh, test_progs-no_alu32, test_progs, test_xsk.sh, test_sockmap, test_maps), breakpoints (except step_after_suspend_test), capabilities, cgroup (except test_freezer), clone3, core, cpu-hotplug, cpufreq, drivers/dma-buf, drivers/net/bonding, drivers/net/team, efivarfs, filesystems/binderfs, filesystems, firmware, fpu, ftrace, futex, gpio, intel_pstate, ipc, ir, kcmp, kvm, landlock, lib, livepatch, membarrier, memfd, memory-hotplug, mincore, mount, mqueue, nci, net/forwarding (except mirror_gre_bridge_1d_vlan.sh, sch_tbf_root.sh, sch_red.sh, ipip_hier_gre_keys.sh, vxlan_bridge_1d_ipv6.sh, sch_tbf_prio.sh, tc_police.sh, tc_actions.sh, gre_inner_v6_multipath.sh, sch_tbf_ets.sh, q_in_vni.sh, sch_ets.sh, mirror_gre_vlan_bridge_1q.sh), net/mptcp (except mptcp_join.sh, userspace_pm.sh, simult_flows.sh), net (except xfrm_policy.sh, gro.sh, udpgro_fwd.sh, fib_nexthops.sh, reuseaddr_conflict, ip_defrag.sh, txtimestamp.sh, reuseport_addr_any.sh), netfilter (except nft_trans_stress.sh), nsfs, openat2, pid_namespace, pidfd, proc (except proc-uptime-001), pstore, ptrace, rlimits, rseq, seccomp, sgx, sigaltstack, size, splice, static_keys, syscall_user_dispatch, tc-testing, tdx, timens, timers, tmpfs, tpm2, vDSO, vm, zram

Reference

bpf:get_cgroup_id_user - net:vrf_strict_mode_test.sh batch:
kselftests–ciqlts9_2–run1.log
kselftests–ciqlts9_2–run2.log

net/forwarding:tc_shblocks.sh - zram:zram.sh batch:
kselftests–ciqlts9_2–run3.log
kselftests–ciqlts9_2–run4.log
kselftests–ciqlts9_2–run5.log

Patch

bpf:get_cgroup_id_user - net:vrf_strict_mode_test.sh batch:
kselftests–ciqlts9_2-CVE-2024-26598–run1.log
kselftests–ciqlts9_2-CVE-2024-26598–run2.log

net/forwarding:tc_shblocks.sh - zram:zram.sh batch:
kselftests–ciqlts9_2-CVE-2024-26598–run3.log
kselftests–ciqlts9_2-CVE-2024-26598–run4.log
kselftests–ciqlts9_2-CVE-2024-26598–run5.log

Comparison

The test results are the same for the reference kernel and the patch.

$ ktests.xsh diff -d kselftests*.log

Column    File
--------  ----------------------------------------------
Status0   kselftests--ciqlts9_2--run1.log
Status1   kselftests--ciqlts9_2--run2.log
Status2   kselftests--ciqlts9_2--run3.log
Status3   kselftests--ciqlts9_2--run4.log
Status4   kselftests--ciqlts9_2--run5.log
Status5   kselftests--ciqlts9_2-CVE-2024-26598--run1.log
Status6   kselftests--ciqlts9_2-CVE-2024-26598--run2.log
Status7   kselftests--ciqlts9_2-CVE-2024-26598--run3.log
Status8   kselftests--ciqlts9_2-CVE-2024-26598--run4.log
Status9   kselftests--ciqlts9_2-CVE-2024-26598--run5.log

Specific tests: skipped

Footnotes

1 https://www.nxp.com/products/LS1046A

2 https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/armv8-a-architecture-2016-additions

3 https://en.wikipedia.org/wiki/ARM_architecture_family

4 https://en.wikipedia.org/wiki/Comparison_of_ARM_processors#ARMv8-A

jira VULN-8190
cve CVE-2024-26598
commit-author Oliver Upton <oliver.upton@linux.dev>
commit ad362fe

There is a potential UAF scenario in the case of an LPI translation
cache hit racing with an operation that invalidates the cache, such
as a DISCARD ITS command. The root of the problem is that
vgic_its_check_cache() does not elevate the refcount on the vgic_irq
before dropping the lock that serializes refcount changes.

Have vgic_its_check_cache() raise the refcount on the returned vgic_irq
and add the corresponding decrement after queueing the interrupt.

	Cc: stable@vger.kernel.org
	Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
	Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20240104183233.3560639-1-oliver.upton@linux.dev
(cherry picked from commit ad362fe)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
Copy link
Collaborator

@bmastbergen bmastbergen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥌

Copy link

@thefossguy-ciq thefossguy-ciq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚤

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants