CVE-2026-45908
Description
In the Linux kernel, the following vulnerability has been resolved:
accel/amdxdna: Fix memory leak in amdxdna_ubuf_map
The amdxdna_ubuf_map() function allocates memory for sg and internal sg table structures, but it fails to free them if subsequent operations (sg_alloc_table_from_pages or dma_map_sgtable) fail.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Linux kernel memory leak in accel/amdxdna driver where allocated memory for scatterlist tables is not freed on failure.
Vulnerability
In the Linux kernel, a memory leak exists in the accel/amdxdna driver's amdxdna_ubuf_map() function. This function allocates memory for an sg (scatterlist) pointer and internal scatterlist table structures using kmalloc and sg_alloc_table. However, if subsequent operations such as sg_alloc_table_from_pages or dma_map_sgtable fail, the previously allocated memory is not freed, causing a memory leak. The affected versions are those containing this commit prior to the fix (stable kernel versions up to the patched commit [1]).
Exploitation
An attacker needs to trigger a failure in either sg_alloc_table_from_pages or dma_map_sgtable within the amdxdna_ubuf_map() function. This may be achieved by causing a memory allocation failure (e.g., exhausting system memory) or by providing invalid parameters that cause the DMA mapping to fail. No special privileges are required beyond the ability to interact with the affected driver via the amdxdna device.
Impact
Successful exploitation leads to a memory leak in the kernel, which can result in gradual depletion of system memory, potentially causing denial of service (availability impact) over time. There is no confidentiality or integrity impact directly from the leak itself, but excessive memory consumption may degrade system performance or cause instability.
Mitigation
The fix is provided in the Linux kernel stable commit [1], which ensures that the allocated memory is properly freed on error paths. Users should apply the kernel patch containing commit 5a68d2c99c859e6e8e36fa4e32749abf6d1fb66a or update to a kernel version that includes this fix. No workarounds are documented.
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
1Patches
684dd57fb0359accel/amdxdna: Fix memory leak in amdxdna_ubuf_map
2 files changed · +16 −6
drivers/accel/amdxdna/amdxdna_ubuf.c+8 −3 modifieddiff --git a/drivers/accel/amdxdna/amdxdna_ubuf.c b/drivers/accel/amdxdna/amdxdna_ubuf.c index 077b2261cf2a04..9e3b3b055caa86 100644 --- a/drivers/accel/amdxdna/amdxdna_ubuf.c +++ b/drivers/accel/amdxdna/amdxdna_ubuf.c @@ -34,15 +34,21 @@ static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach, ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->nr_pages, 0, ubuf->nr_pages << PAGE_SHIFT, GFP_KERNEL); if (ret) - return ERR_PTR(ret); + goto err_free_sg; if (ubuf->flags & AMDXDNA_UBUF_FLAG_MAP_DMA) { ret = dma_map_sgtable(attach->dev, sg, direction, 0); if (ret) - return ERR_PTR(ret); + goto err_free_table; } return sg; + +err_free_table: + sg_free_table(sg); +err_free_sg: + kfree(sg); + return ERR_PTR(ret); } static void amdxdna_ubuf_unmap(struct dma_buf_attachment *attach, -- cgit 1.3-korg
drivers/accel/amdxdna/amdxdna_ubuf.c+8 −3 modifieddiff --git a/drivers/accel/amdxdna/amdxdna_ubuf.c b/drivers/accel/amdxdna/amdxdna_ubuf.c index 077b2261cf2a04..9e3b3b055caa86 100644 --- a/drivers/accel/amdxdna/amdxdna_ubuf.c +++ b/drivers/accel/amdxdna/amdxdna_ubuf.c @@ -34,15 +34,21 @@ static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach, ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->nr_pages, 0, ubuf->nr_pages << PAGE_SHIFT, GFP_KERNEL); if (ret) - return ERR_PTR(ret); + goto err_free_sg; if (ubuf->flags & AMDXDNA_UBUF_FLAG_MAP_DMA) { ret = dma_map_sgtable(attach->dev, sg, direction, 0); if (ret) - return ERR_PTR(ret); + goto err_free_table; } return sg; + +err_free_table: + sg_free_table(sg); +err_free_sg: + kfree(sg); + return ERR_PTR(ret); } static void amdxdna_ubuf_unmap(struct dma_buf_attachment *attach, -- cgit 1.3-korg
5a68d2c99c85accel/amdxdna: Fix memory leak in amdxdna_ubuf_map
2 files changed · +16 −6
drivers/accel/amdxdna/amdxdna_ubuf.c+8 −3 modifieddiff --git a/drivers/accel/amdxdna/amdxdna_ubuf.c b/drivers/accel/amdxdna/amdxdna_ubuf.c index 077b2261cf2a04..9e3b3b055caa86 100644 --- a/drivers/accel/amdxdna/amdxdna_ubuf.c +++ b/drivers/accel/amdxdna/amdxdna_ubuf.c @@ -34,15 +34,21 @@ static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach, ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->nr_pages, 0, ubuf->nr_pages << PAGE_SHIFT, GFP_KERNEL); if (ret) - return ERR_PTR(ret); + goto err_free_sg; if (ubuf->flags & AMDXDNA_UBUF_FLAG_MAP_DMA) { ret = dma_map_sgtable(attach->dev, sg, direction, 0); if (ret) - return ERR_PTR(ret); + goto err_free_table; } return sg; + +err_free_table: + sg_free_table(sg); +err_free_sg: + kfree(sg); + return ERR_PTR(ret); } static void amdxdna_ubuf_unmap(struct dma_buf_attachment *attach, -- cgit 1.3-korg
drivers/accel/amdxdna/amdxdna_ubuf.c+8 −3 modifieddiff --git a/drivers/accel/amdxdna/amdxdna_ubuf.c b/drivers/accel/amdxdna/amdxdna_ubuf.c index 077b2261cf2a04..9e3b3b055caa86 100644 --- a/drivers/accel/amdxdna/amdxdna_ubuf.c +++ b/drivers/accel/amdxdna/amdxdna_ubuf.c @@ -34,15 +34,21 @@ static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach, ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->nr_pages, 0, ubuf->nr_pages << PAGE_SHIFT, GFP_KERNEL); if (ret) - return ERR_PTR(ret); + goto err_free_sg; if (ubuf->flags & AMDXDNA_UBUF_FLAG_MAP_DMA) { ret = dma_map_sgtable(attach->dev, sg, direction, 0); if (ret) - return ERR_PTR(ret); + goto err_free_table; } return sg; + +err_free_table: + sg_free_table(sg); +err_free_sg: + kfree(sg); + return ERR_PTR(ret); } static void amdxdna_ubuf_unmap(struct dma_buf_attachment *attach, -- cgit 1.3-korg
f9f4366d2ff9accel/amdxdna: Fix memory leak in amdxdna_ubuf_map
2 files changed · +16 −6
drivers/accel/amdxdna/amdxdna_ubuf.c+8 −3 modifieddiff --git a/drivers/accel/amdxdna/amdxdna_ubuf.c b/drivers/accel/amdxdna/amdxdna_ubuf.c index 077b2261cf2a04..9e3b3b055caa86 100644 --- a/drivers/accel/amdxdna/amdxdna_ubuf.c +++ b/drivers/accel/amdxdna/amdxdna_ubuf.c @@ -34,15 +34,21 @@ static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach, ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->nr_pages, 0, ubuf->nr_pages << PAGE_SHIFT, GFP_KERNEL); if (ret) - return ERR_PTR(ret); + goto err_free_sg; if (ubuf->flags & AMDXDNA_UBUF_FLAG_MAP_DMA) { ret = dma_map_sgtable(attach->dev, sg, direction, 0); if (ret) - return ERR_PTR(ret); + goto err_free_table; } return sg; + +err_free_table: + sg_free_table(sg); +err_free_sg: + kfree(sg); + return ERR_PTR(ret); } static void amdxdna_ubuf_unmap(struct dma_buf_attachment *attach, -- cgit 1.3-korg
drivers/accel/amdxdna/amdxdna_ubuf.c+8 −3 modifieddiff --git a/drivers/accel/amdxdna/amdxdna_ubuf.c b/drivers/accel/amdxdna/amdxdna_ubuf.c index 077b2261cf2a04..9e3b3b055caa86 100644 --- a/drivers/accel/amdxdna/amdxdna_ubuf.c +++ b/drivers/accel/amdxdna/amdxdna_ubuf.c @@ -34,15 +34,21 @@ static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach, ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->nr_pages, 0, ubuf->nr_pages << PAGE_SHIFT, GFP_KERNEL); if (ret) - return ERR_PTR(ret); + goto err_free_sg; if (ubuf->flags & AMDXDNA_UBUF_FLAG_MAP_DMA) { ret = dma_map_sgtable(attach->dev, sg, direction, 0); if (ret) - return ERR_PTR(ret); + goto err_free_table; } return sg; + +err_free_table: + sg_free_table(sg); +err_free_sg: + kfree(sg); + return ERR_PTR(ret); } static void amdxdna_ubuf_unmap(struct dma_buf_attachment *attach, -- cgit 1.3-korg
5a68d2c99c85accel/amdxdna: Fix memory leak in amdxdna_ubuf_map
2 files changed · +16 −6
drivers/accel/amdxdna/amdxdna_ubuf.c+8 −3 modifieddiff --git a/drivers/accel/amdxdna/amdxdna_ubuf.c b/drivers/accel/amdxdna/amdxdna_ubuf.c index 077b2261cf2a04..9e3b3b055caa86 100644 --- a/drivers/accel/amdxdna/amdxdna_ubuf.c +++ b/drivers/accel/amdxdna/amdxdna_ubuf.c @@ -34,15 +34,21 @@ static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach, ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->nr_pages, 0, ubuf->nr_pages << PAGE_SHIFT, GFP_KERNEL); if (ret) - return ERR_PTR(ret); + goto err_free_sg; if (ubuf->flags & AMDXDNA_UBUF_FLAG_MAP_DMA) { ret = dma_map_sgtable(attach->dev, sg, direction, 0); if (ret) - return ERR_PTR(ret); + goto err_free_table; } return sg; + +err_free_table: + sg_free_table(sg); +err_free_sg: + kfree(sg); + return ERR_PTR(ret); } static void amdxdna_ubuf_unmap(struct dma_buf_attachment *attach, -- cgit 1.3-korg
drivers/accel/amdxdna/amdxdna_ubuf.c+8 −3 modifieddiff --git a/drivers/accel/amdxdna/amdxdna_ubuf.c b/drivers/accel/amdxdna/amdxdna_ubuf.c index 077b2261cf2a04..9e3b3b055caa86 100644 --- a/drivers/accel/amdxdna/amdxdna_ubuf.c +++ b/drivers/accel/amdxdna/amdxdna_ubuf.c @@ -34,15 +34,21 @@ static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach, ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->nr_pages, 0, ubuf->nr_pages << PAGE_SHIFT, GFP_KERNEL); if (ret) - return ERR_PTR(ret); + goto err_free_sg; if (ubuf->flags & AMDXDNA_UBUF_FLAG_MAP_DMA) { ret = dma_map_sgtable(attach->dev, sg, direction, 0); if (ret) - return ERR_PTR(ret); + goto err_free_table; } return sg; + +err_free_table: + sg_free_table(sg); +err_free_sg: + kfree(sg); + return ERR_PTR(ret); } static void amdxdna_ubuf_unmap(struct dma_buf_attachment *attach, -- cgit 1.3-korg
84dd57fb0359accel/amdxdna: Fix memory leak in amdxdna_ubuf_map
2 files changed · +16 −6
drivers/accel/amdxdna/amdxdna_ubuf.c+8 −3 modifieddiff --git a/drivers/accel/amdxdna/amdxdna_ubuf.c b/drivers/accel/amdxdna/amdxdna_ubuf.c index 077b2261cf2a04..9e3b3b055caa86 100644 --- a/drivers/accel/amdxdna/amdxdna_ubuf.c +++ b/drivers/accel/amdxdna/amdxdna_ubuf.c @@ -34,15 +34,21 @@ static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach, ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->nr_pages, 0, ubuf->nr_pages << PAGE_SHIFT, GFP_KERNEL); if (ret) - return ERR_PTR(ret); + goto err_free_sg; if (ubuf->flags & AMDXDNA_UBUF_FLAG_MAP_DMA) { ret = dma_map_sgtable(attach->dev, sg, direction, 0); if (ret) - return ERR_PTR(ret); + goto err_free_table; } return sg; + +err_free_table: + sg_free_table(sg); +err_free_sg: + kfree(sg); + return ERR_PTR(ret); } static void amdxdna_ubuf_unmap(struct dma_buf_attachment *attach, -- cgit 1.3-korg
drivers/accel/amdxdna/amdxdna_ubuf.c+8 −3 modifieddiff --git a/drivers/accel/amdxdna/amdxdna_ubuf.c b/drivers/accel/amdxdna/amdxdna_ubuf.c index 077b2261cf2a04..9e3b3b055caa86 100644 --- a/drivers/accel/amdxdna/amdxdna_ubuf.c +++ b/drivers/accel/amdxdna/amdxdna_ubuf.c @@ -34,15 +34,21 @@ static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach, ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->nr_pages, 0, ubuf->nr_pages << PAGE_SHIFT, GFP_KERNEL); if (ret) - return ERR_PTR(ret); + goto err_free_sg; if (ubuf->flags & AMDXDNA_UBUF_FLAG_MAP_DMA) { ret = dma_map_sgtable(attach->dev, sg, direction, 0); if (ret) - return ERR_PTR(ret); + goto err_free_table; } return sg; + +err_free_table: + sg_free_table(sg); +err_free_sg: + kfree(sg); + return ERR_PTR(ret); } static void amdxdna_ubuf_unmap(struct dma_buf_attachment *attach, -- cgit 1.3-korg
f9f4366d2ff9accel/amdxdna: Fix memory leak in amdxdna_ubuf_map
2 files changed · +16 −6
drivers/accel/amdxdna/amdxdna_ubuf.c+8 −3 modifieddiff --git a/drivers/accel/amdxdna/amdxdna_ubuf.c b/drivers/accel/amdxdna/amdxdna_ubuf.c index 077b2261cf2a04..9e3b3b055caa86 100644 --- a/drivers/accel/amdxdna/amdxdna_ubuf.c +++ b/drivers/accel/amdxdna/amdxdna_ubuf.c @@ -34,15 +34,21 @@ static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach, ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->nr_pages, 0, ubuf->nr_pages << PAGE_SHIFT, GFP_KERNEL); if (ret) - return ERR_PTR(ret); + goto err_free_sg; if (ubuf->flags & AMDXDNA_UBUF_FLAG_MAP_DMA) { ret = dma_map_sgtable(attach->dev, sg, direction, 0); if (ret) - return ERR_PTR(ret); + goto err_free_table; } return sg; + +err_free_table: + sg_free_table(sg); +err_free_sg: + kfree(sg); + return ERR_PTR(ret); } static void amdxdna_ubuf_unmap(struct dma_buf_attachment *attach, -- cgit 1.3-korg
drivers/accel/amdxdna/amdxdna_ubuf.c+8 −3 modifieddiff --git a/drivers/accel/amdxdna/amdxdna_ubuf.c b/drivers/accel/amdxdna/amdxdna_ubuf.c index 077b2261cf2a04..9e3b3b055caa86 100644 --- a/drivers/accel/amdxdna/amdxdna_ubuf.c +++ b/drivers/accel/amdxdna/amdxdna_ubuf.c @@ -34,15 +34,21 @@ static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach, ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->nr_pages, 0, ubuf->nr_pages << PAGE_SHIFT, GFP_KERNEL); if (ret) - return ERR_PTR(ret); + goto err_free_sg; if (ubuf->flags & AMDXDNA_UBUF_FLAG_MAP_DMA) { ret = dma_map_sgtable(attach->dev, sg, direction, 0); if (ret) - return ERR_PTR(ret); + goto err_free_table; } return sg; + +err_free_table: + sg_free_table(sg); +err_free_sg: + kfree(sg); + return ERR_PTR(ret); } static void amdxdna_ubuf_unmap(struct dma_buf_attachment *attach, -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing error-path cleanup: the function allocates memory for `sg` and its internal scatter-gather table but returns directly on failure without freeing those allocations."
Attack vector
An attacker triggers a memory leak by causing either `sg_alloc_table_from_pages()` or `dma_map_sgtable()` to fail inside `amdxdna_ubuf_map()` [patch_id=2661475]. The function allocates a `struct sg_table` via `kzalloc` and then populates it, but on error it returned `ERR_PTR(ret)` without calling `kfree(sg)` or `sg_free_table(sg)`. Repeated failures exhaust kernel memory, leading to denial of service. No special privileges are required beyond the ability to interact with the amdxdna accelerator device.
Affected code
The vulnerable function is `amdxdna_ubuf_map()` in `drivers/accel/amdxdna/amdxdna_ubuf.c` [patch_id=2661475]. The function allocates a `struct sg_table` via `kzalloc` and then calls `sg_alloc_table_from_pages()` and optionally `dma_map_sgtable()`. Both error paths returned `ERR_PTR(ret)` without freeing the previously allocated memory.
What the fix does
The patch replaces the two early `return ERR_PTR(ret)` statements with `goto` jumps to new error labels [patch_id=2661475]. The `err_free_table` label calls `sg_free_table(sg)` to release the internal sg table memory, and `err_free_sg` calls `kfree(sg)` to free the sg structure itself. This ensures all allocated memory is properly freed before returning an error pointer.
Preconditions
- authThe attacker must be able to interact with the amdxdna accelerator device driver, typically through a DMA-buf attachment.
- configThe system must be running a kernel version containing the vulnerable amdxdna_ubuf_map() function (introduced by commit bd72d4acda10).
- inputThe attacker must cause sg_alloc_table_from_pages() or dma_map_sgtable() to fail (e.g., by exhausting memory or providing invalid parameters).
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
3News mentions
0No linked articles in our index yet.