Offering: HULK hulk inclusion category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/14416 CVE: CVE-2026-31588 -------------------------------- Since kvm_run.s reserved 2048 bytes in struct tail, we can use this space to extend new variable. This CVE is related to x86, we just only add mmio_scratch array in tail of x86 kvm_sync_regs This struct is only 512 bytes now, and avoid calculating CRC KABI by adding "#ifndef __GENKSYMS__". Fixes: 1d1c75630e81 ("[Backport] KVM: x86: Use scratch field in MMIO fragment to hold small write values") Signed-off-by: Xinyu Zheng <zhengxinyu6@huawei.com> Reviewed-by: Wang Yanan <wangyanan55@huawei.com> Tested-by: Zhang Yashu <zhangyashu2@h-partners.com> --- arch/x86/include/uapi/asm/kvm.h | 3 +++ arch/x86/kvm/x86.c | 9 +++++---- include/linux/kvm_host.h | 3 +-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h index 1a6a1f987949..1bb5a403a5b9 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -429,6 +429,9 @@ struct kvm_sync_regs { struct kvm_regs regs; struct kvm_sregs sregs; struct kvm_vcpu_events events; +#ifndef __GENKSYMS__ + __u64 mmio_scratch[2]; +#endif }; #define KVM_X86_QUIRK_LINT0_REENABLED (1 << 0) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 9e2ddf5f19eb..0581528f8bb2 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7899,9 +7899,9 @@ static int emulator_read_write_onepage(unsigned long addr, void *val, frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; frag->gpa = gpa; if (write && bytes <= 8u) { - frag->val = 0; - frag->data = &frag->val; - memcpy(&frag->val, val, bytes); + frag->data = &vcpu->run->s.regs.mmio_scratch[vcpu->mmio_nr_fragments - 1]; + memset(frag->data, 0, sizeof(u64)); + memcpy(frag->data, val, bytes); } else { frag->data = val; } @@ -11359,7 +11359,8 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) frag++; vcpu->mmio_cur_fragment++; } else { - if (WARN_ON_ONCE(frag->data == &frag->val)) + if (WARN_ON_ONCE(frag->data == &vcpu->run->s.regs.mmio_scratch[0] || + frag->data == &vcpu->run->s.regs.mmio_scratch[1])) return -EIO; /* Go forward to the next mmio piece. */ diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 383a34b87c8c..4cea2db862a6 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -323,8 +323,7 @@ static inline bool kvm_vcpu_can_poll(ktime_t cur, ktime_t stop) struct kvm_mmio_fragment { gpa_t gpa; void *data; - u64 val; - unsigned int len; + unsigned len; }; struct kvm_vcpu { -- 2.34.1