From nobody Wed Dec 17 14:44:01 2025 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 579C5CDB47E for ; Wed, 18 Oct 2023 20:46:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232358AbjJRUql (ORCPT ); Wed, 18 Oct 2023 16:46:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34270 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232082AbjJRUqf (ORCPT ); Wed, 18 Oct 2023 16:46:35 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0A3679B for ; Wed, 18 Oct 2023 13:46:34 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id 3f1490d57ef6-d9a3a98b34dso10019765276.3 for ; Wed, 18 Oct 2023 13:46:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1697661993; x=1698266793; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=0NC3yqMcGjhIZrhf7725DJ1Gf8NkzsIha09da8LPGz0=; b=SmAaQ7putaQ3J9cjAp0JVUn0Kcd12FMuMq4Sl67CevF4CgsKROoWDvmmhp3kRKmGLQ 3QMt7nCvyNMn7/TFbNaLtmuM7W+jWyrJx6vhg9hOs//AB0sYdKhmYfjuvEDYhfHy+/ju hqMbQ99fiBxOGENlnGXhYSN1A2GlE19mlS2vnmOs0GdbeNYKPaYrs/2LZWJ/ohWYLZ6R RGqPv03UwwsBO6mI5aqAQQYJa8ot68Pq5M12HKzDhajzxXBa2DsN/Bxc0gXxGr7gxWgn eR6jmqBHFekWlaHqzNduMj7a5id4JgQewCu1IAA474hxqINCASw/k/HGprLiHz7ytne+ Rtsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697661993; x=1698266793; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=0NC3yqMcGjhIZrhf7725DJ1Gf8NkzsIha09da8LPGz0=; b=ce50dm3SPBGswXVCg5wQu8yAUZsBtp+mTHAbIyj816Q9lT7tcR3wgj/knt3XbdccTX vYWEApDz+MzSCez7N4rcHsoDMene+dZHQipCouSrxprIq64tPvJKGyG/UhdfGB22d56C RDgHbjOZmnadJxsFVKDDMXiKqn87WWKQpeoTsOOcRArirNd0a/FLfq2m2ZDzT+225TOF ocg1jlsMZBQnXwrm9MNcLXt8X0SQLp5UglgjNnusssZby2//ObnhkI4HV/bZsST/YNR+ 5UiSAXpY02bXom48S3LHdfvepVdsEhIMyi4/ByIOaNURZ51IlxsPglCyjJCG15bYwKXI deYA== X-Gm-Message-State: AOJu0YxRu0sE6Fr9B1b48m3vvfpcgRzRAC/5HLCunaEH4YxA3jhZaehT ZvN3ZTH+foN9nvmpB/efbfP42eYTFzQ= X-Google-Smtp-Source: AGHT+IG+aew8QqUeKJhMjafkL3+AfUCVwG2CQNeHZsBiKSQcnY9Z1RYn+qlTT/sPLTnhnGPz3wPUHZUiY+E= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a05:6902:134a:b0:d9a:58e0:c7c7 with SMTP id g10-20020a056902134a00b00d9a58e0c7c7mr11788ybu.1.1697661993300; Wed, 18 Oct 2023 13:46:33 -0700 (PDT) Reply-To: Sean Christopherson Date: Wed, 18 Oct 2023 13:46:22 -0700 In-Reply-To: <20231018204624.1905300-1-seanjc@google.com> Mime-Version: 1.0 References: <20231018204624.1905300-1-seanjc@google.com> X-Mailer: git-send-email 2.42.0.655.g421f12c284-goog Message-ID: <20231018204624.1905300-2-seanjc@google.com> Subject: [PATCH 1/3] KVM: Set file_operations.owner appropriately for all such structures From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Al Viro , David Matlack Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Set .owner for all KVM-owned filed types so that the KVM module is pinned until any files with callbacks back into KVM are completely freed. Using "struct kvm" as a proxy for the module, i.e. keeping KVM-the-module alive while there are active VMs, doesn't provide full protection. Userspace can invoke delete_module() the instant the last reference to KVM is put. If KVM itself puts the last reference, e.g. via kvm_destroy_vm(), then it's possible for KVM to be preempted and deleted/unloaded before KVM fully exits, e.g. when the task running kvm_destroy_vm() is scheduled back in, it will jump to a code page that is no longer mapped. Note, file types that can call into sub-module code, e.g. kvm-intel.ko or kvm-amd.ko on x86, must use the module pointer passed to kvm_init(), not THIS_MODULE (which points at kvm.ko). KVM assumes that if /dev/kvm is reachable, e.g. VMs are active, then the vendor module is loaded. To reduce the probability of forgetting to set .owner entirely, use THIS_MODULE for stats files where KVM does not call back into vendor code. This reverts commit 70375c2d8fa3fb9b0b59207a9c5df1e2e1205c10, and fixes several other file types that have been buggy since their introduction. Fixes: 70375c2d8fa3 ("Revert "KVM: set owner of cpu and vm file operations"= ") Fixes: 3bcd0662d66f ("KVM: X86: Introduce mmu_rmaps_stat per-vm debugfs fil= e") Reported-by: Al Viro Link: https://lore.kernel.org/all/20231010003746.GN800259@ZenIV Signed-off-by: Sean Christopherson --- arch/x86/kvm/debugfs.c | 1 + virt/kvm/kvm_main.c | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/debugfs.c b/arch/x86/kvm/debugfs.c index ee8c4c3496ed..eea6ea7f14af 100644 --- a/arch/x86/kvm/debugfs.c +++ b/arch/x86/kvm/debugfs.c @@ -182,6 +182,7 @@ static int kvm_mmu_rmaps_stat_release(struct inode *ino= de, struct file *file) } =20 static const struct file_operations mmu_rmaps_stat_fops =3D { + .owner =3D THIS_MODULE, .open =3D kvm_mmu_rmaps_stat_open, .read =3D seq_read, .llseek =3D seq_lseek, diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 486800a7024b..1e65a506985f 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -3887,7 +3887,7 @@ static int kvm_vcpu_release(struct inode *inode, stru= ct file *filp) return 0; } =20 -static const struct file_operations kvm_vcpu_fops =3D { +static struct file_operations kvm_vcpu_fops =3D { .release =3D kvm_vcpu_release, .unlocked_ioctl =3D kvm_vcpu_ioctl, .mmap =3D kvm_vcpu_mmap, @@ -4081,6 +4081,7 @@ static int kvm_vcpu_stats_release(struct inode *inode= , struct file *file) } =20 static const struct file_operations kvm_vcpu_stats_fops =3D { + .owner =3D THIS_MODULE, .read =3D kvm_vcpu_stats_read, .release =3D kvm_vcpu_stats_release, .llseek =3D noop_llseek, @@ -4431,7 +4432,7 @@ static int kvm_device_release(struct inode *inode, st= ruct file *filp) return 0; } =20 -static const struct file_operations kvm_device_fops =3D { +static struct file_operations kvm_device_fops =3D { .unlocked_ioctl =3D kvm_device_ioctl, .release =3D kvm_device_release, KVM_COMPAT(kvm_device_ioctl), @@ -4759,6 +4760,7 @@ static int kvm_vm_stats_release(struct inode *inode, = struct file *file) } =20 static const struct file_operations kvm_vm_stats_fops =3D { + .owner =3D THIS_MODULE, .read =3D kvm_vm_stats_read, .release =3D kvm_vm_stats_release, .llseek =3D noop_llseek, @@ -5060,7 +5062,7 @@ static long kvm_vm_compat_ioctl(struct file *filp, } #endif =20 -static const struct file_operations kvm_vm_fops =3D { +static struct file_operations kvm_vm_fops =3D { .release =3D kvm_vm_release, .unlocked_ioctl =3D kvm_vm_ioctl, .llseek =3D noop_llseek, @@ -6095,6 +6097,9 @@ int kvm_init(unsigned vcpu_size, unsigned vcpu_align,= struct module *module) goto err_async_pf; =20 kvm_chardev_ops.owner =3D module; + kvm_vm_fops.owner =3D module; + kvm_vcpu_fops.owner =3D module; + kvm_device_fops.owner =3D module; =20 kvm_preempt_ops.sched_in =3D kvm_sched_in; kvm_preempt_ops.sched_out =3D kvm_sched_out; --=20 2.42.0.655.g421f12c284-goog