diff options
author | Thomas Huth <thuth@linux.vnet.ibm.com> | 2014-03-20 08:20:46 -0400 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2014-03-25 08:27:11 -0400 |
commit | 91880d07fc9b2b6b7a726765039897af99d9ca78 (patch) | |
tree | ac9073770af435f86dfc8f8dc616dae436aaff5a /arch/s390/kvm | |
parent | 609433fbed4f25e11e8b058ab7e9478b212879a9 (diff) |
KVM: s390: Fix possible memory leak in SIGP functions
When kvm_get_vcpu() returned NULL for the destination CPU in
__sigp_emergency() or __sigp_external_call(), the memory for the
"inti" structure was not released anymore. This patch fixes this
issue by moving the check for !dst_vcpu before the kzalloc() call.
Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r-- | arch/s390/kvm/sigp.c | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 3fe44c441609..26caeb530a78 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c | |||
@@ -58,7 +58,9 @@ static int __sigp_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
58 | struct kvm_s390_interrupt_info *inti; | 58 | struct kvm_s390_interrupt_info *inti; |
59 | struct kvm_vcpu *dst_vcpu = NULL; | 59 | struct kvm_vcpu *dst_vcpu = NULL; |
60 | 60 | ||
61 | if (cpu_addr >= KVM_MAX_VCPUS) | 61 | if (cpu_addr < KVM_MAX_VCPUS) |
62 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
63 | if (!dst_vcpu) | ||
62 | return SIGP_CC_NOT_OPERATIONAL; | 64 | return SIGP_CC_NOT_OPERATIONAL; |
63 | 65 | ||
64 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); | 66 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); |
@@ -68,9 +70,6 @@ static int __sigp_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
68 | inti->type = KVM_S390_INT_EMERGENCY; | 70 | inti->type = KVM_S390_INT_EMERGENCY; |
69 | inti->emerg.code = vcpu->vcpu_id; | 71 | inti->emerg.code = vcpu->vcpu_id; |
70 | 72 | ||
71 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
72 | if (!dst_vcpu) | ||
73 | return SIGP_CC_NOT_OPERATIONAL; | ||
74 | li = &dst_vcpu->arch.local_int; | 73 | li = &dst_vcpu->arch.local_int; |
75 | spin_lock_bh(&li->lock); | 74 | spin_lock_bh(&li->lock); |
76 | list_add_tail(&inti->list, &li->list); | 75 | list_add_tail(&inti->list, &li->list); |
@@ -121,7 +120,9 @@ static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
121 | struct kvm_s390_interrupt_info *inti; | 120 | struct kvm_s390_interrupt_info *inti; |
122 | struct kvm_vcpu *dst_vcpu = NULL; | 121 | struct kvm_vcpu *dst_vcpu = NULL; |
123 | 122 | ||
124 | if (cpu_addr >= KVM_MAX_VCPUS) | 123 | if (cpu_addr < KVM_MAX_VCPUS) |
124 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
125 | if (!dst_vcpu) | ||
125 | return SIGP_CC_NOT_OPERATIONAL; | 126 | return SIGP_CC_NOT_OPERATIONAL; |
126 | 127 | ||
127 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); | 128 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); |
@@ -131,9 +132,6 @@ static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
131 | inti->type = KVM_S390_INT_EXTERNAL_CALL; | 132 | inti->type = KVM_S390_INT_EXTERNAL_CALL; |
132 | inti->extcall.code = vcpu->vcpu_id; | 133 | inti->extcall.code = vcpu->vcpu_id; |
133 | 134 | ||
134 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
135 | if (!dst_vcpu) | ||
136 | return SIGP_CC_NOT_OPERATIONAL; | ||
137 | li = &dst_vcpu->arch.local_int; | 135 | li = &dst_vcpu->arch.local_int; |
138 | spin_lock_bh(&li->lock); | 136 | spin_lock_bh(&li->lock); |
139 | list_add_tail(&inti->list, &li->list); | 137 | list_add_tail(&inti->list, &li->list); |