Skip to content

Commit 53936b5

Browse files
huthborntraeger
authored andcommitted
KVM: s390: Do not leak kernel stack data in the KVM_S390_INTERRUPT ioctl
When the userspace program runs the KVM_S390_INTERRUPT ioctl to inject an interrupt, we convert them from the legacy struct kvm_s390_interrupt to the new struct kvm_s390_irq via the s390int_to_s390irq() function. However, this function does not take care of all types of interrupts that we can inject into the guest later (see do_inject_vcpu()). Since we do not clear out the s390irq values before calling s390int_to_s390irq(), there is a chance that we copy random data from the kernel stack which could be leaked to the userspace later. Specifically, the problem exists with the KVM_S390_INT_PFAULT_INIT interrupt: s390int_to_s390irq() does not handle it, and the function __inject_pfault_init() later copies irq->u.ext which contains the random kernel stack data. This data can then be leaked either to the guest memory in __deliver_pfault_init(), or the userspace might retrieve it directly with the KVM_S390_GET_IRQ_STATE ioctl. Fix it by handling that interrupt type in s390int_to_s390irq(), too, and by making sure that the s390irq struct is properly pre-initialized. And while we're at it, make sure that s390int_to_s390irq() now directly returns -EINVAL for unknown interrupt types, so that we immediately get a proper error code in case we add more interrupt types to do_inject_vcpu() without updating s390int_to_s390irq() sometime in the future. Cc: [email protected] Reviewed-by: David Hildenbrand <[email protected]> Reviewed-by: Christian Borntraeger <[email protected]> Reviewed-by: Janosch Frank <[email protected]> Signed-off-by: Thomas Huth <[email protected]> Link: https://lore.kernel.org/kvm/[email protected] Signed-off-by: Christian Borntraeger <[email protected]>
1 parent 13a17cc commit 53936b5

File tree

2 files changed

+11
-1
lines changed

2 files changed

+11
-1
lines changed

arch/s390/kvm/interrupt.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1961,6 +1961,16 @@ int s390int_to_s390irq(struct kvm_s390_interrupt *s390int,
19611961
case KVM_S390_MCHK:
19621962
irq->u.mchk.mcic = s390int->parm64;
19631963
break;
1964+
case KVM_S390_INT_PFAULT_INIT:
1965+
irq->u.ext.ext_params = s390int->parm;
1966+
irq->u.ext.ext_params2 = s390int->parm64;
1967+
break;
1968+
case KVM_S390_RESTART:
1969+
case KVM_S390_INT_CLOCK_COMP:
1970+
case KVM_S390_INT_CPU_TIMER:
1971+
break;
1972+
default:
1973+
return -EINVAL;
19641974
}
19651975
return 0;
19661976
}

arch/s390/kvm/kvm-s390.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4335,7 +4335,7 @@ long kvm_arch_vcpu_async_ioctl(struct file *filp,
43354335
}
43364336
case KVM_S390_INTERRUPT: {
43374337
struct kvm_s390_interrupt s390int;
4338-
struct kvm_s390_irq s390irq;
4338+
struct kvm_s390_irq s390irq = {};
43394339

43404340
if (copy_from_user(&s390int, argp, sizeof(s390int)))
43414341
return -EFAULT;

0 commit comments

Comments
 (0)