VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-45931

CVE-2026-45931

Description

In the Linux kernel, the following vulnerability has been resolved:

accel/amdxdna: Hold mm structure across iommu_sva_unbind_device()

Some tests trigger a crash in iommu_sva_unbind_device() due to accessing iommu_mm after the associated mm structure has been freed.

Fix this by taking an explicit reference to the mm structure after successfully binding the device, and releasing it only after the device is unbound. This ensures the mm remains valid for the entire SVA bind/unbind lifetime.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A use-after-free vulnerability in the Linux kernel's amdxdna SVA unbind path could crash the system; fixed by properly holding an mm reference.

Vulnerability

In the Linux kernel's amdxdna accelerator driver, the SVA (Shared Virtual Addressing) unbind operation could access iommu_mm after the associated mm structure had been freed. This occurs during iommu_sva_unbind_device() due to a missing reference count on the mm structure. The vulnerability affects kernel versions prior to the fix commit a9162439ad79 [1].

Exploitation

An attacker needs local access to trigger the SVA unbind path, possibly by unloading a driver or ending a process that used the accelerator. No special privileges are required beyond being able to use the amdxdna device. The race window between mm release and unbind can be exploited to cause a use-after-free on iommu_mm.

Impact

Successful exploitation leads to a kernel crash (denial of service). Potential for further exploitation in a use-after-free scenario is limited by the complexity of the race, but memory corruption could theoretically be leveraged for privilege escalation.

Mitigation

Fixed in Linux kernel commit a9162439ad792afcddc04718408ec1380b7a5f63 [1]. Update to a kernel containing this fix. No known workaround.

AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2

Patches

6
a9162439ad79

accel/amdxdna: Hold mm structure across iommu_sva_unbind_device()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitLizhi HouJan 28, 2026Fixed in 7.0via kernel-cna
2 files changed · +4 1
  • drivers/accel/amdxdna/amdxdna_pci_drv.c+3 0 modified
    diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c
    index 45f5c12fc67fbf..fdefd9ec206688 100644
    --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c
    +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c
    @@ -82,6 +82,8 @@ static int amdxdna_drm_open(struct drm_device *ddev, struct drm_file *filp)
     		ret = -ENODEV;
     		goto unbind_sva;
     	}
    +	client->mm = current->mm;
    +	mmgrab(client->mm);
     	init_srcu_struct(&client->hwctx_srcu);
     	xa_init_flags(&client->hwctx_xa, XA_FLAGS_ALLOC);
     	mutex_init(&client->mm_lock);
    @@ -116,6 +118,7 @@ static void amdxdna_client_cleanup(struct amdxdna_client *client)
     		drm_gem_object_put(to_gobj(client->dev_heap));
     
     	iommu_sva_unbind_device(client->sva);
    +	mmdrop(client->mm);
     
     	kfree(client);
     }
    
  • drivers/accel/amdxdna/amdxdna_pci_drv.h+1 1 modified
    diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.h b/drivers/accel/amdxdna/amdxdna_pci_drv.h
    index 6580cb5ec7e2f6..f08406b8fdf939 100644
    --- a/drivers/accel/amdxdna/amdxdna_pci_drv.h
    +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.h
    @@ -130,6 +130,7 @@ struct amdxdna_client {
     
     	struct iommu_sva		*sva;
     	int				pasid;
    +	struct mm_struct		*mm;
     };
     
     #define amdxdna_for_each_hwctx(client, hwctx_id, entry)		\
    -- 
    cgit 1.3-korg
    
    
    
f6b4c1d98a7b

accel/amdxdna: Hold mm structure across iommu_sva_unbind_device()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitLizhi HouJan 28, 2026Fixed in 6.18.14via kernel-cna
2 files changed · +4 1
  • drivers/accel/amdxdna/amdxdna_pci_drv.c+3 0 modified
    diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c
    index ccf2d1de558c0f..88643e28af84b9 100644
    --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c
    +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c
    @@ -88,6 +88,8 @@ static int amdxdna_drm_open(struct drm_device *ddev, struct drm_file *filp)
     		ret = -ENODEV;
     		goto unbind_sva;
     	}
    +	client->mm = current->mm;
    +	mmgrab(client->mm);
     	init_srcu_struct(&client->hwctx_srcu);
     	xa_init_flags(&client->hwctx_xa, XA_FLAGS_ALLOC);
     	mutex_init(&client->mm_lock);
    @@ -127,6 +129,7 @@ static void amdxdna_drm_close(struct drm_device *ddev, struct drm_file *filp)
     		drm_gem_object_put(to_gobj(client->dev_heap));
     
     	iommu_sva_unbind_device(client->sva);
    +	mmdrop(client->mm);
     
     	XDNA_DBG(xdna, "pid %d closed", client->pid);
     	kfree(client);
    
  • drivers/accel/amdxdna/amdxdna_pci_drv.h+1 1 modified
    diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.h b/drivers/accel/amdxdna/amdxdna_pci_drv.h
    index 72d6696d49da81..64009ca2498271 100644
    --- a/drivers/accel/amdxdna/amdxdna_pci_drv.h
    +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.h
    @@ -128,6 +128,7 @@ struct amdxdna_client {
     
     	struct iommu_sva		*sva;
     	int				pasid;
    +	struct mm_struct		*mm;
     };
     
     #define amdxdna_for_each_hwctx(client, hwctx_id, entry)		\
    -- 
    cgit 1.3-korg
    
    
    
f31ccf627813

accel/amdxdna: Hold mm structure across iommu_sva_unbind_device()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitLizhi HouJan 28, 2026Fixed in 6.19.4via kernel-cna
2 files changed · +4 1
  • drivers/accel/amdxdna/amdxdna_pci_drv.c+3 0 modified
    diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c
    index fcc9be23b3de50..bcb0d77b63cbb5 100644
    --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c
    +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c
    @@ -83,6 +83,8 @@ static int amdxdna_drm_open(struct drm_device *ddev, struct drm_file *filp)
     		ret = -ENODEV;
     		goto unbind_sva;
     	}
    +	client->mm = current->mm;
    +	mmgrab(client->mm);
     	init_srcu_struct(&client->hwctx_srcu);
     	xa_init_flags(&client->hwctx_xa, XA_FLAGS_ALLOC);
     	mutex_init(&client->mm_lock);
    @@ -119,6 +121,7 @@ static void amdxdna_drm_close(struct drm_device *ddev, struct drm_file *filp)
     		drm_gem_object_put(to_gobj(client->dev_heap));
     
     	iommu_sva_unbind_device(client->sva);
    +	mmdrop(client->mm);
     
     	XDNA_DBG(xdna, "pid %d closed", client->pid);
     	kfree(client);
    
  • drivers/accel/amdxdna/amdxdna_pci_drv.h+1 1 modified
    diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.h b/drivers/accel/amdxdna/amdxdna_pci_drv.h
    index 0d50c4c8b35333..ec21cb378a472a 100644
    --- a/drivers/accel/amdxdna/amdxdna_pci_drv.h
    +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.h
    @@ -130,6 +130,7 @@ struct amdxdna_client {
     
     	struct iommu_sva		*sva;
     	int				pasid;
    +	struct mm_struct		*mm;
     };
     
     #define amdxdna_for_each_hwctx(client, hwctx_id, entry)		\
    -- 
    cgit 1.3-korg
    
    
    
a9162439ad79

accel/amdxdna: Hold mm structure across iommu_sva_unbind_device()

2 files changed · +4 1
  • drivers/accel/amdxdna/amdxdna_pci_drv.c+3 0 modified
    diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c
    index 45f5c12fc67fbf..fdefd9ec206688 100644
    --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c
    +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c
    @@ -82,6 +82,8 @@ static int amdxdna_drm_open(struct drm_device *ddev, struct drm_file *filp)
     		ret = -ENODEV;
     		goto unbind_sva;
     	}
    +	client->mm = current->mm;
    +	mmgrab(client->mm);
     	init_srcu_struct(&client->hwctx_srcu);
     	xa_init_flags(&client->hwctx_xa, XA_FLAGS_ALLOC);
     	mutex_init(&client->mm_lock);
    @@ -116,6 +118,7 @@ static void amdxdna_client_cleanup(struct amdxdna_client *client)
     		drm_gem_object_put(to_gobj(client->dev_heap));
     
     	iommu_sva_unbind_device(client->sva);
    +	mmdrop(client->mm);
     
     	kfree(client);
     }
    
  • drivers/accel/amdxdna/amdxdna_pci_drv.h+1 1 modified
    diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.h b/drivers/accel/amdxdna/amdxdna_pci_drv.h
    index 6580cb5ec7e2f6..f08406b8fdf939 100644
    --- a/drivers/accel/amdxdna/amdxdna_pci_drv.h
    +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.h
    @@ -130,6 +130,7 @@ struct amdxdna_client {
     
     	struct iommu_sva		*sva;
     	int				pasid;
    +	struct mm_struct		*mm;
     };
     
     #define amdxdna_for_each_hwctx(client, hwctx_id, entry)		\
    -- 
    cgit 1.3-korg
    
    
    
f31ccf627813

accel/amdxdna: Hold mm structure across iommu_sva_unbind_device()

2 files changed · +4 1
  • drivers/accel/amdxdna/amdxdna_pci_drv.c+3 0 modified
    diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c
    index fcc9be23b3de50..bcb0d77b63cbb5 100644
    --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c
    +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c
    @@ -83,6 +83,8 @@ static int amdxdna_drm_open(struct drm_device *ddev, struct drm_file *filp)
     		ret = -ENODEV;
     		goto unbind_sva;
     	}
    +	client->mm = current->mm;
    +	mmgrab(client->mm);
     	init_srcu_struct(&client->hwctx_srcu);
     	xa_init_flags(&client->hwctx_xa, XA_FLAGS_ALLOC);
     	mutex_init(&client->mm_lock);
    @@ -119,6 +121,7 @@ static void amdxdna_drm_close(struct drm_device *ddev, struct drm_file *filp)
     		drm_gem_object_put(to_gobj(client->dev_heap));
     
     	iommu_sva_unbind_device(client->sva);
    +	mmdrop(client->mm);
     
     	XDNA_DBG(xdna, "pid %d closed", client->pid);
     	kfree(client);
    
  • drivers/accel/amdxdna/amdxdna_pci_drv.h+1 1 modified
    diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.h b/drivers/accel/amdxdna/amdxdna_pci_drv.h
    index 0d50c4c8b35333..ec21cb378a472a 100644
    --- a/drivers/accel/amdxdna/amdxdna_pci_drv.h
    +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.h
    @@ -130,6 +130,7 @@ struct amdxdna_client {
     
     	struct iommu_sva		*sva;
     	int				pasid;
    +	struct mm_struct		*mm;
     };
     
     #define amdxdna_for_each_hwctx(client, hwctx_id, entry)		\
    -- 
    cgit 1.3-korg
    
    
    
f6b4c1d98a7b

accel/amdxdna: Hold mm structure across iommu_sva_unbind_device()

2 files changed · +4 1
  • drivers/accel/amdxdna/amdxdna_pci_drv.c+3 0 modified
    diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c
    index ccf2d1de558c0f..88643e28af84b9 100644
    --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c
    +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c
    @@ -88,6 +88,8 @@ static int amdxdna_drm_open(struct drm_device *ddev, struct drm_file *filp)
     		ret = -ENODEV;
     		goto unbind_sva;
     	}
    +	client->mm = current->mm;
    +	mmgrab(client->mm);
     	init_srcu_struct(&client->hwctx_srcu);
     	xa_init_flags(&client->hwctx_xa, XA_FLAGS_ALLOC);
     	mutex_init(&client->mm_lock);
    @@ -127,6 +129,7 @@ static void amdxdna_drm_close(struct drm_device *ddev, struct drm_file *filp)
     		drm_gem_object_put(to_gobj(client->dev_heap));
     
     	iommu_sva_unbind_device(client->sva);
    +	mmdrop(client->mm);
     
     	XDNA_DBG(xdna, "pid %d closed", client->pid);
     	kfree(client);
    
  • drivers/accel/amdxdna/amdxdna_pci_drv.h+1 1 modified
    diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.h b/drivers/accel/amdxdna/amdxdna_pci_drv.h
    index 72d6696d49da81..64009ca2498271 100644
    --- a/drivers/accel/amdxdna/amdxdna_pci_drv.h
    +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.h
    @@ -128,6 +128,7 @@ struct amdxdna_client {
     
     	struct iommu_sva		*sva;
     	int				pasid;
    +	struct mm_struct		*mm;
     };
     
     #define amdxdna_for_each_hwctx(client, hwctx_id, entry)		\
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Use-after-free: the mm_struct referenced by the IOMMU SVA binding could be freed before iommu_sva_unbind_device() finishes accessing it, because no explicit reference was held across the bind/unbind lifetime."

Attack vector

An unprivileged local user can trigger the bug by opening and closing an AMD XDNA accelerator DRM device file (via amdxdna_drm_open / amdxdna_drm_close). When the process exits or closes the file descriptor, the kernel tears down the process's mm_struct. If iommu_sva_unbind_device() is called after the mm has been freed, it accesses freed memory (iommu_mm), causing a crash. No special privileges or network access are required; the attacker only needs access to the /dev/dri device node for the amdxdna driver.

Affected code

The bug is in `drivers/accel/amdxdna/amdxdna_pci_drv.c` in the `amdxdna_drm_open()` and `amdxdna_client_cleanup()` (or `amdxdna_drm_close()`) functions. The header `drivers/accel/amdxdna/amdxdna_pci_drv.h` is also modified to add the `mm` pointer to `struct amdxdna_client`.

What the fix does

The patch adds a new `mm` field to `struct amdxdna_client` [patch_id=2661239]. In `amdxdna_drm_open()`, after a successful SVA bind, the driver stores `current->mm` and calls `mmgrab()` to take an explicit reference on the mm_struct. In the cleanup path (`amdxdna_client_cleanup()` or `amdxdna_drm_close()`), `mmdrop()` is called *after* `iommu_sva_unbind_device()`. This ordering guarantees that the mm_struct remains alive for the entire duration of the unbind operation, preventing the use-after-free crash.

Preconditions

  • inputAttacker must have access to the AMD XDNA accelerator DRM device (e.g., /dev/dri/renderD*).
  • configThe amdxdna kernel driver must be loaded and the device must support SVA (Shared Virtual Addressing).

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

3

News mentions

0

No linked articles in our index yet.