From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751627AbbIKHqi (ORCPT ); Fri, 11 Sep 2015 03:46:38 -0400 Received: from e06smtp15.uk.ibm.com ([195.75.94.111]:52745 "EHLO e06smtp15.uk.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751196AbbIKHqh (ORCPT ); Fri, 11 Sep 2015 03:46:37 -0400 X-Helo: d06dlp02.portsmouth.uk.ibm.com X-MailFrom: cornelia.huck@de.ibm.com X-RcptTo: linux-kernel@vger.kernel.org Date: Fri, 11 Sep 2015 09:46:31 +0200 From: Cornelia Huck To: Jason Wang Cc: gleb@kernel.org, pbonzini@redhat.com, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, mst@redhat.com Subject: Re: [PATCH V4 2/4] kvm: fix double free for fast mmio eventfd Message-ID: <20150911094631.107a4435.cornelia.huck@de.ibm.com> In-Reply-To: <1441941457-23630-3-git-send-email-jasowang@redhat.com> References: <1441941457-23630-1-git-send-email-jasowang@redhat.com> <1441941457-23630-3-git-send-email-jasowang@redhat.com> Organization: IBM Deutschland Research & Development GmbH Vorsitzende des Aufsichtsrats: Martina Koederitz =?UTF-8?B?R2VzY2jDpGZ0c2bDvGhydW5nOg==?= Dirk Wittkopp Sitz der Gesellschaft: =?UTF-8?B?QsO2Ymxpbmdlbg==?= Registergericht: Amtsgericht Stuttgart, HRB 243294 X-Mailer: Claws Mail 3.8.0 (GTK+ 2.24.10; i686-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15091107-0021-0000-0000-000005443902 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, 11 Sep 2015 11:17:35 +0800 Jason Wang wrote: > We register wildcard mmio eventfd on two buses, one for KVM_MMIO_BUS > and another is KVM_FAST_MMIO_BUS but with a single iodev > instance. This will lead an issue: kvm_io_bus_destroy() knows nothing > about the devices on two buses points to a single dev. Which will lead s/points/pointing/ > double free[1] during exit. Fixing this by using allocate two s/using allocate/allocating/ > instances of iodevs then register one on KVM_MMIO_BUS and another on > KVM_FAST_MMIO_BUS. > (...) > @@ -929,8 +878,66 @@ kvm_deassign_ioeventfd_idx(struct kvm *kvm, enum kvm_bus bus_idx, > static int kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) > { > enum kvm_bus bus_idx = ioeventfd_bus_from_flags(args->flags); > + int ret = kvm_deassign_ioeventfd_idx(kvm, bus_idx, args); > + > + if (!args->len) > + kvm_deassign_ioeventfd_idx(kvm, KVM_FAST_MMIO_BUS, args); I think it would be good to explicitly check for bus_idx == KVM_MMIO_BUS here. > + > + return ret; > +} > > - return kvm_deassign_ioeventfd_idx(kvm, bus_idx, args); > +static int > +kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) > +{ > + enum kvm_bus bus_idx; > + int ret; > + > + bus_idx = ioeventfd_bus_from_flags(args->flags); > + /* must be natural-word sized, or 0 to ignore length */ > + switch (args->len) { > + case 0: > + case 1: > + case 2: > + case 4: > + case 8: > + break; > + default: > + return -EINVAL; > + } > + > + /* check for range overflow */ > + if (args->addr + args->len < args->addr) > + return -EINVAL; > + > + /* check for extra flags that we don't understand */ > + if (args->flags & ~KVM_IOEVENTFD_VALID_FLAG_MASK) > + return -EINVAL; > + > + /* ioeventfd with no length can't be combined with DATAMATCH */ > + if (!args->len && > + args->flags & (KVM_IOEVENTFD_FLAG_PIO | > + KVM_IOEVENTFD_FLAG_DATAMATCH)) > + return -EINVAL; > + > + ret = kvm_assign_ioeventfd_idx(kvm, bus_idx, args); > + if (ret) > + goto fail; > + > + /* When length is ignored, MMIO is also put on a separate bus, for > + * faster lookups. > + */ > + if (!args->len && !(args->flags & KVM_IOEVENTFD_FLAG_PIO)) { Dito on a positive check for bus_idx == KVM_MMIO_BUS. > + ret = kvm_assign_ioeventfd_idx(kvm, KVM_FAST_MMIO_BUS, args); > + if (ret < 0) > + goto fast_fail; > + } > + > + return 0; > + > +fast_fail: > + kvm_deassign_ioeventfd(kvm, args); Shouldn't you use kvm_deassign_ioeventfd(kvm, bus_idx, args) here? > +fail: > + return ret; > } > > int