[PATCH] drm/nouveau: disable VM_BIND once a legacy BO VMA is created

Zhenhao Wan <[email protected]>
Newsgroups org.freedesktop.lists.nouveau,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
nouveau_gem_object_open() creates a legacy per-client VMA when the client
has not initialised VM_BIND (!nouveau_cli_uvmm()), but
nouveau_gem_object_close() only tears it down while the client is still not
a VM_BIND client ("if (nouveau_cli_uvmm(cli)) return;").

nouveau_gem_ioctl_new() calls nouveau_cli_disable_uvmm_noinit() to stop a
client mixing the legacy and VM_BIND uAPIs, but the prime-import and flink
GEM_OPEN paths that also run nouveau_gem_object_open() do not. A client can
thus open an object (creating a legacy VMA), call NOUVEAU_VM_INIT, then
close the handle: close() now returns early and leaks the VMA. If the BO is
flink-shared it outlives the client's freed vmm, and the next migration
walks nvbo->vma_list in nouveau_bo_move_ntfy() and dereferences the stale
vma->vmm -- a use-after-free.

Disable VM_BIND in nouveau_gem_object_open() as nouveau_gem_ioctl_new()
does; the helper is a no-op once VM_BIND is initialised, so VM_BIND-first
clients are unaffected.

Fixes: b88baab82871 ("drm/nouveau: implement new VM_BIND uAPI")
Reported-by: Yuhao Jiang <[email protected]>
Assisted-by: Claude:claude-opus-5
Cc: [email protected]
Signed-off-by: Zhenhao Wan <[email protected]>
---
 drivers/gpu/drm/nouveau/nouveau_gem.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 20dba02d6175..e33f76b5a239 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -108,6 +108,14 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
 	if (vmm->vmm.object.oclass < NVIF_CLASS_VMM_NV50)
 		return 0;
 
+	/*
+	 * Opening the object binds it through the legacy per-VMA path below.
+	 * Disable VM_BIND for this client, as nouveau_gem_ioctl_new() does, so
+	 * a later NOUVEAU_VM_INIT cannot switch the client to uvmm and leave
+	 * nouveau_gem_object_close() unable to tear this VMA down.
+	 */
+	nouveau_cli_disable_uvmm_noinit(cli);
+
 	if (nvbo->no_share && uvmm &&
 	    drm_gpuvm_resv(&uvmm->base) != nvbo->bo.base.resv)
 		return -EPERM;

---
base-commit: db2ddb87143519e20a95aa36c60b36107b736a58
change-id: 20260813-nouveau-gem-uvmm-vma-fix-8d0fbac454b9

Best regards,
--  
Zhenhao Wan <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.