Re: [BUG REPORT] USE_AFTER_FREE in complete_emulated_mmio found by KASAN/Syzkaller fuzz test (v5.10.0)
From: Xinyu
Date: Fri May 08 2026 - 21:56:02 EST
On 5/8/2026 10:25 PM, Sean Christopherson wrote:
On Fri, May 08, 2026, Xinyu Zheng wrote:
On 2/19/2026 4:56 AM, Sean Christopherson wrote:
On Tue, Feb 10, 2026, Sean Christopherson wrote:
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 2c7d76262898..0bb2a34fb93d 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -320,7 +320,8 @@ static inline bool kvm_vcpu_can_poll(ktime_t cur, ktime_t stop)
struct kvm_mmio_fragment {
gpa_t gpa;
void *data;
- unsigned len;
+ u64 val;
Hi, Jiayi and Sean,
Since I met a KABI consistence break problem from this change, I am finding
a way to avoid add including kvm_mmio_fragment.val.
I assume you're looking for a solution for a private/proprietary kernel? I.e.
not trying to figure out a solution for an upstream LTS kernel?
Yes.
Can I try to directly malloc a 8 size buffer for kvm_mmio_fragment.data
instead of using kvm_mmio_fragment.val, and free this buffer in
complete_emulated_mmio when all fragments is been copied?
I highly doubt that will work, because you'd still need to stash the pointer
somewhere. And it pretty much would have to be somewhere in kvm_vcpu, which
would likely mean a change in KABI. FWIW, freeing the allocation in
complete_emulated_mmio() wouldn't suffice; you'd also need to free the memory
on vCPU destruction, because there's no guarantee userspace would complete
KVM_RUN.
Thanks for your correction and patient reply!
You should be able to use the padding in the "kvm_run.s". Thanks to s390's
massive regs size, there's a huge amount of unused space in the union on x86.
Note, because there can be two fragments in-flight, you'd need to index the
array using the correct fragment number.
Userspace can scribble the value, but that's completely irrelevant from a host
safety perspective.
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 6c8afa2047bf..29c7123d5467 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -515,7 +515,10 @@ struct kvm_run {
__u64 kvm_valid_regs;
__u64 kvm_dirty_regs;
union {
- struct kvm_sync_regs regs;
+ struct {
+ struct kvm_sync_regs regs;
+ u64 x86_mmio_val[2];
+ };
char padding[SYNC_REGS_SIZE_BYTES];
} s;
};
I will take this suggestion.
--
Xinyu Zheng