From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C329AC433FE for ; Tue, 24 May 2022 05:52:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234596AbiEXFwU (ORCPT ); Tue, 24 May 2022 01:52:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45764 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231499AbiEXFwS (ORCPT ); Tue, 24 May 2022 01:52:18 -0400 Received: from ozlabs.ru (ozlabs.ru [107.174.27.60]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 787F7612A1; Mon, 23 May 2022 22:52:16 -0700 (PDT) Received: from fstn1-p1.ozlabs.ibm.com. (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id B029180560; Tue, 24 May 2022 01:52:13 -0400 (EDT) From: Alexey Kardashevskiy To: kvm@vger.kernel.org Cc: Alexey Kardashevskiy , Paolo Bonzini , kvm-ppc@vger.kernel.org Subject: [PATCH kernel] KVM: Don't null dereference ops->destroy Date: Tue, 24 May 2022 15:52:08 +1000 Message-Id: <20220524055208.1269279-1-aik@ozlabs.ru> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org There are 2 places calling kvm_device_ops::destroy(): 1) when creating a KVM device failed; 2) when a VM is destroyed: kvm_destroy_devices() destroys all devices from &kvm->devices. All 3 Book3s's interrupt controller KVM devices (XICS, XIVE, XIVE-native) do not define kvm_device_ops::destroy() and only define release() which is normally fine as device fds are closed before KVM gets to 2) but by then the &kvm->devices list is empty. However Syzkaller manages to trigger 1). This adds checks in 1) and 2). Signed-off-by: Alexey Kardashevskiy --- I could define empty handlers for XICS/XIVE guys but kvm_ioctl_create_device() already checks for ops->init() so I guess kvm_device_ops are expected to not have certain handlers. --- virt/kvm/kvm_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f30bb8c16f26..17f698ccddd1 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1205,7 +1205,8 @@ static void kvm_destroy_devices(struct kvm *kvm) */ list_for_each_entry_safe(dev, tmp, &kvm->devices, vm_node) { list_del(&dev->vm_node); - dev->ops->destroy(dev); + if (dev->ops->destroy) + dev->ops->destroy(dev); } } @@ -4300,7 +4301,8 @@ static int kvm_ioctl_create_device(struct kvm *kvm, mutex_lock(&kvm->lock); list_del(&dev->vm_node); mutex_unlock(&kvm->lock); - ops->destroy(dev); + if (ops->destroy) + ops->destroy(dev); return ret; } -- 2.30.2 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alexey Kardashevskiy Date: Tue, 24 May 2022 05:52:08 +0000 Subject: [PATCH kernel] KVM: Don't null dereference ops->destroy Message-Id: <20220524055208.1269279-1-aik@ozlabs.ru> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: kvm@vger.kernel.org Cc: Alexey Kardashevskiy , Paolo Bonzini , kvm-ppc@vger.kernel.org There are 2 places calling kvm_device_ops::destroy(): 1) when creating a KVM device failed; 2) when a VM is destroyed: kvm_destroy_devices() destroys all devices from &kvm->devices. All 3 Book3s's interrupt controller KVM devices (XICS, XIVE, XIVE-native) do not define kvm_device_ops::destroy() and only define release() which is normally fine as device fds are closed before KVM gets to 2) but by then the &kvm->devices list is empty. However Syzkaller manages to trigger 1). This adds checks in 1) and 2). Signed-off-by: Alexey Kardashevskiy --- I could define empty handlers for XICS/XIVE guys but kvm_ioctl_create_device() already checks for ops->init() so I guess kvm_device_ops are expected to not have certain handlers. --- virt/kvm/kvm_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f30bb8c16f26..17f698ccddd1 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1205,7 +1205,8 @@ static void kvm_destroy_devices(struct kvm *kvm) */ list_for_each_entry_safe(dev, tmp, &kvm->devices, vm_node) { list_del(&dev->vm_node); - dev->ops->destroy(dev); + if (dev->ops->destroy) + dev->ops->destroy(dev); } } @@ -4300,7 +4301,8 @@ static int kvm_ioctl_create_device(struct kvm *kvm, mutex_lock(&kvm->lock); list_del(&dev->vm_node); mutex_unlock(&kvm->lock); - ops->destroy(dev); + if (ops->destroy) + ops->destroy(dev); return ret; } -- 2.30.2