Skip to content

Commit b8be70e

Browse files
committed
KVM: VMX: Ensure unused kvm_tdx_capabilities fields are zeroed out
Zero-allocate the kernel's kvm_tdx_capabilities structure and copy only the number of CPUID entries from the userspace structure. As is, KVM doesn't ensure kernel_tdvmcallinfo_1_{r11,r12} and user_tdvmcallinfo_1_r12 are zeroed, i.e. KVM will reflect whatever happens to be in the userspace structure back at userspace, and thus may report garbage to userspace. Zeroing the entire kernel structure also provides better semantics for the reserved field. E.g. if KVM extends kvm_tdx_capabilities to enumerate new information by repurposing bytes from the reserved field, userspace would be required to zero the new field in order to get useful information back (because older KVMs without support for the repurposed field would report garbage, a la the aforementioned tdvmcallinfo bugs). Fixes: 61bb282 ("KVM: TDX: Get system-wide info about TDX module on initialization") Suggested-by: Rick Edgecombe <[email protected]> Reported-by: Xiaoyao Li <[email protected]> Closes: https://lore.kernel.org/all/[email protected] Tested-by: Xiaoyao Li <[email protected]> Reviewed-by: Xiaoyao Li <[email protected]> Reviewed-by: Rick Edgecombe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sean Christopherson <[email protected]>
1 parent b24bbb5 commit b8be70e

File tree

1 file changed

+4
-3
lines changed

1 file changed

+4
-3
lines changed

arch/x86/kvm/vmx/tdx.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2271,25 +2271,26 @@ static int tdx_get_capabilities(struct kvm_tdx_cmd *cmd)
22712271
const struct tdx_sys_info_td_conf *td_conf = &tdx_sysinfo->td_conf;
22722272
struct kvm_tdx_capabilities __user *user_caps;
22732273
struct kvm_tdx_capabilities *caps = NULL;
2274+
u32 nr_user_entries;
22742275
int ret = 0;
22752276

22762277
/* flags is reserved for future use */
22772278
if (cmd->flags)
22782279
return -EINVAL;
22792280

2280-
caps = kmalloc(sizeof(*caps) +
2281+
caps = kzalloc(sizeof(*caps) +
22812282
sizeof(struct kvm_cpuid_entry2) * td_conf->num_cpuid_config,
22822283
GFP_KERNEL);
22832284
if (!caps)
22842285
return -ENOMEM;
22852286

22862287
user_caps = u64_to_user_ptr(cmd->data);
2287-
if (copy_from_user(caps, user_caps, sizeof(*caps))) {
2288+
if (get_user(nr_user_entries, &user_caps->cpuid.nent)) {
22882289
ret = -EFAULT;
22892290
goto out;
22902291
}
22912292

2292-
if (caps->cpuid.nent < td_conf->num_cpuid_config) {
2293+
if (nr_user_entries < td_conf->num_cpuid_config) {
22932294
ret = -E2BIG;
22942295
goto out;
22952296
}

0 commit comments

Comments
 (0)