Xen-guest hosting under KVM (hypercall interception)¶
KVM, Xen ABI'sini emüle ederek Xen PV/HVM guest'lerini barındırabilir: hypercall page'ine sahip olur, Xen hypercall'larını
KVM_EXIT_XENüzerinden userspace'e intercept eder ve event channel'ları ile shared-info/runstate page'leriniKVM_XEN_*ioctl'leri aracılığıyla emüle eder.
Mechanism¶
Note
KVM'in Xen emulation'ı (CONFIG_KVM_XEN ile kapılanır, KVM_CAP_XEN_HVM ile
duyurulur) bir Xen guest'inin Xen olmadan bir KVM host'unda çalışmasını sağlar.
Host VMM KVM_XEN_HVM_CONFIG'i yapılandırır; KVM ardından Xen hypercall MSR'ını
handle eder (guest'in hypercall page'ini kurmak için yazdığı index, [0x40000000,
0x4fffffff] synthetic aralığıyla sınırlıdır) ve KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL
flag'i ile KVM hypercall page'ini kendisi doldurur (VMCALL/VMMCALL stub'ları)
ve hypercall'ları intercept ederek bunları KVM_EXIT_XEN exit'i üzerinden
userspace'e iletir. Artık ABI'ye KVM sahip olduğu için, hypercall decode/dispatch
ve event-channel handling bir in-kernel attack surface'i hâline gelir — ilgili
bir fuzzing/hardening hedefi. Xen-native ABI ile karşılaştırın:
Xen PV hypercalls.
Walkthrough¶
Mainline KVM API dokümantasyonundan (Xen ABI'si Documentation/virt/kvm/api.rst
içinde belgelenmiştir; mevcut mainline'da ayrı bir x86/xen.rst yoktur).
Hypercall interception loop'u:
/* On KVM_EXIT_XEN with KVM_EXIT_XEN_HCALL, userspace handles the hypercall */
struct kvm_xen_exit {
#define KVM_EXIT_XEN_HCALL 1
__u32 type;
union {
struct {
__u32 longmode;
__u32 cpl;
__u64 input; /* hypercall number */
__u64 result; /* userspace writes the return value */
__u64 params[6]; /* hypercall arguments */
} hcall;
} u;
};
Userspace hypercall'ı işler, result'ı yazar ve KVM_RUN'a yeniden girer.
Xen state configuration ioctls
VM seviyesinde KVM_XEN_HVM_SET_ATTR (struct kvm_xen_hvm_attr):
KVM_XEN_ATTR_TYPE_LONG_MODE, KVM_XEN_ATTR_TYPE_SHARED_INFO (Xen shared_info
page'inin GFN'i; KVM_XEN_INVALID_GFN devre dışı bırakır),
..._SHARED_INFO_HVA, ..._UPCALL_VECTOR, ..._EVTCHN (EVTCHNOP_send'i
intercept etmek için bir outbound port yapılandırır; flag'ler
KVM_XEN_EVTCHN_UPDATE/_DEASSIGN/_RESET), ..._XEN_VERSION,
..._RUNSTATE_UPDATE_FLAG.
vCPU seviyesinde KVM_XEN_VCPU_SET_ATTR (struct kvm_xen_vcpu_attr):
..._VCPU_INFO (+ _VCPU_INFO_HVA), ..._VCPU_TIME_INFO,
..._RUNSTATE_*, ..._VCPU_ID, ..._TIMER (VIRQ_TIMER için event-channel
port/priority), ..._UPCALL_VECTOR. KVM vcpu_info'yu shared_info içine
otomatik yerleştirmez — userspace bunu açıkça set etmelidir, çünkü KVM
vcpu_info[]'yu index'lemek için kullanılan Xen CPU id'sini bilmeyebilir.
Event-channel IRQ routing: KVM_IRQ_ROUTING_XEN_EVTCHN ile struct
kvm_irq_routing_xen_evtchn { __u32 port; __u32 vcpu; __u32 priority; },
KVM_CAP_XEN_HVM KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL duyurduğunda desteklenir
(2-level delivery; FIFO gelecekteki iş). KVM_XEN_HVM_EVTCHN_SEND ioctl'i
event-channel interrupt'larını iletir (ve örneğin PV spinlock'ları hızlandırmak
için KVM'in SCHEDOP_poll'u intercept etmesine olanak tanır — bkz.
KVM paravirtualized spinlocks).
Detection¶
- Emulation
CONFIG_KVM_XEN/KVM_CAP_XEN_HVMile kapılanır; varlığı, surface olarak in-kernel hypercall decode/dispatch ve event-channel send interception ekler. KVM shared_info/vcpu_info'ya "sürekli yazabilir", bu da dirty-logging/migration ile etkileşir — oradaki anomaliler gözlemlenebilirdir.
Mitigation¶
- Bir vulnerability değil; hardening duruşu, intercept edilen hypercall'lar için
KVM ve VMM'de input validation (örneğin MSR aralığının
[0x40000000, 0x4fffffff]ile sınırlanması) ve Xen-guest hosting'in gerekmediği yerlerdeCONFIG_KVM_XEN'in devre dışı bırakılmasıdır. Hypercall interface'i tanınmış bir fuzzing hedefidir.
References¶
- "The Definitive KVM (Kernel-based Virtual Machine) API Documentation"
(
Documentation/virt/kvm/api.rst, mainline), https://raw.githubusercontent.com/torvalds/linux/master/Documentation/virt/kvm/api.rst - Linux commit "KVM: x86/xen: intercept xen hypercalls if enabled", https://github.com/0day-ci/linux/commit/9e109a13c92b207e4edbaf4b8ccb22a32ffcb587