Message ID | 1452204661-62519-2-git-send-email-brad.figg@canonical.com |
---|---|
State | New |
Headers | show |
Please add the cherry-picked/backported from 0185604c2d82c560dab2f2933a18f797e74ab5a8 line here. ACK one this is done. --chris On 01/07/2016 04:11 PM, Brad Figg wrote: > From: Andrew Honig <ahonig@google.com> > > BugLink: http://bugs.launchpad.net/bugs/1530956 > > Currently if userspace restores the pit counters with a count of 0 > on channels 1 or 2 and the guest attempts to read the count on those > channels, then KVM will perform a mod of 0 and crash. This will ensure > that 0 values are converted to 65536 as per the spec. > > This is CVE-2015-7513. > > Signed-off-by: Andy Honig <ahonig@google.com> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> > Signed-off-by: Brad Figg <brad.figg@canonical.com> > --- > arch/x86/kvm/x86.c | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index a18ca2e7..00631db 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -2923,10 +2923,12 @@ static int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps) > static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps) > { > int r = 0; > + int i; > > mutex_lock(&kvm->arch.vpit->pit_state.lock); > memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state)); > - kvm_pit_load_count(kvm, 0, ps->channels[0].count, 0); > + for (i = 0; i < 3; i++) > + kvm_pit_load_count(kvm, i, ps->channels[i].count, 0); > mutex_unlock(&kvm->arch.vpit->pit_state.lock); > return r; > } > @@ -2947,6 +2949,7 @@ static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) > static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) > { > int r = 0, start = 0; > + int i; > u32 prev_legacy, cur_legacy; > mutex_lock(&kvm->arch.vpit->pit_state.lock); > prev_legacy = kvm->arch.vpit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY; > @@ -2956,7 +2959,8 @@ static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) > memcpy(&kvm->arch.vpit->pit_state.channels, &ps->channels, > sizeof(kvm->arch.vpit->pit_state.channels)); > kvm->arch.vpit->pit_state.flags = ps->flags; > - kvm_pit_load_count(kvm, 0, kvm->arch.vpit->pit_state.channels[0].count, start); > + for (i = 0; i < 3; i++) > + kvm_pit_load_count(kvm, i, kvm->arch.vpit->pit_state.channels[i].count, start); > mutex_unlock(&kvm->arch.vpit->pit_state.lock); > return r; > } >
Needs 'backported from commit 0185604c2d82c560dab2f2933a18f797e74ab5a8' in the commit log.
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a18ca2e7..00631db 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2923,10 +2923,12 @@ static int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps) static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps) { int r = 0; + int i; mutex_lock(&kvm->arch.vpit->pit_state.lock); memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state)); - kvm_pit_load_count(kvm, 0, ps->channels[0].count, 0); + for (i = 0; i < 3; i++) + kvm_pit_load_count(kvm, i, ps->channels[i].count, 0); mutex_unlock(&kvm->arch.vpit->pit_state.lock); return r; } @@ -2947,6 +2949,7 @@ static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) { int r = 0, start = 0; + int i; u32 prev_legacy, cur_legacy; mutex_lock(&kvm->arch.vpit->pit_state.lock); prev_legacy = kvm->arch.vpit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY; @@ -2956,7 +2959,8 @@ static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) memcpy(&kvm->arch.vpit->pit_state.channels, &ps->channels, sizeof(kvm->arch.vpit->pit_state.channels)); kvm->arch.vpit->pit_state.flags = ps->flags; - kvm_pit_load_count(kvm, 0, kvm->arch.vpit->pit_state.channels[0].count, start); + for (i = 0; i < 3; i++) + kvm_pit_load_count(kvm, i, kvm->arch.vpit->pit_state.channels[i].count, start); mutex_unlock(&kvm->arch.vpit->pit_state.lock); return r; }