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

CVE-2026-45853

CVE-2026-45853

Description

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

drm/amdgpu: Use kvfree instead of kfree in amdgpu_gmc_get_nps_memranges()

amdgpu_discovery_get_nps_info() internally allocates memory for ranges using kvcalloc(), which may use vmalloc() for large allocation. Using kfree() to release vmalloc memory will lead to a memory corruption.

Use kvfree() to safely handle both kmalloc and vmalloc allocations.

Compile tested only. Issue found using a prototype static analysis tool and code review.

AI Insight

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

A missing kvfree() in amdgpu_gmc_get_nps_memranges() can cause memory corruption because kfree() cannot safely free vmalloc memory allocated by kvcalloc().

Vulnerability

In the Linux kernel's AMDGPU driver, the function amdgpu_gmc_get_nps_memranges() in drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c uses kfree() to release memory that was allocated by kvcalloc() via amdgpu_discovery_get_nps_info(). Since kvcalloc() may use vmalloc() for large allocations, calling kfree() on such memory leads to memory corruption. This affects all kernel versions containing the vulnerable code path, including stable branches. The fix is introduced in commit f441538893eba6347b983f2904819ca6c99da65e [1].

Exploitation

An attacker would need no special privileges; the vulnerability is reachable during GPU initialization when the kernel allocates NPS memory ranges. No user interaction or specific race condition is required beyond normal driver loading on affected hardware. The incorrect free occurs during driver cleanup or error handling.

Impact

Successful exploitation results in memory corruption, which can lead to system instability, denial of service, or potentially arbitrary code execution in kernel context, depending on how the corrupted memory is reused. The attacker gains no direct data disclosure, but the integrity and availability of the system are compromised.

Mitigation

The fix is available in commit f441538893eba6347b983f2904819ca6c99da65e [1]. Users should update to a kernel version containing this patch. No workarounds are documented; the fix simply replaces kfree() with kvfree() to safely handle both kmalloc and vmalloc allocations. The issue is not yet listed on CISA's Known Exploited Vulnerabilities (KEV) catalog.

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

8
f441538893eb

drm/amdgpu: Use kvfree instead of kfree in amdgpu_gmc_get_nps_memranges()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanJan 29, 2026Fixed in 6.19.4via kernel-cna
2 files changed · +2 4
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index d9c7ad297293bd..2b37398337afc3 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1387,7 +1387,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	if (!*exp_ranges)
     		*exp_ranges = range_cnt;
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index d9c7ad297293bd..2b37398337afc3 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1387,7 +1387,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	if (!*exp_ranges)
     		*exp_ranges = range_cnt;
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
0c44d61945c4

drm/amdgpu: Use kvfree instead of kfree in amdgpu_gmc_get_nps_memranges()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanJan 29, 2026Fixed in 7.0via kernel-cna
2 files changed · +2 4
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index b793ce17140c41..d35d9719d56683 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1436,7 +1436,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	if (!*exp_ranges)
     		*exp_ranges = range_cnt;
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index b793ce17140c41..d35d9719d56683 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1436,7 +1436,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	if (!*exp_ranges)
     		*exp_ranges = range_cnt;
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
16e7e7ad8cdc

drm/amdgpu: Use kvfree instead of kfree in amdgpu_gmc_get_nps_memranges()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanJan 29, 2026Fixed in 6.12.75via kernel-cna
2 files changed · +2 4
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index f1596412716726..c57893cce9e3d4 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1260,7 +1260,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	}
     
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index f1596412716726..c57893cce9e3d4 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1260,7 +1260,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	}
     
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
9ae85b0c1909

drm/amdgpu: Use kvfree instead of kfree in amdgpu_gmc_get_nps_memranges()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanJan 29, 2026Fixed in 6.18.14via kernel-cna
2 files changed · +2 4
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index aef1ba1bdca9e3..01ad5cc008a965 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1381,7 +1381,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	if (!*exp_ranges)
     		*exp_ranges = range_cnt;
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index aef1ba1bdca9e3..01ad5cc008a965 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1381,7 +1381,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	if (!*exp_ranges)
     		*exp_ranges = range_cnt;
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
16e7e7ad8cdc

drm/amdgpu: Use kvfree instead of kfree in amdgpu_gmc_get_nps_memranges()

2 files changed · +2 4
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index f1596412716726..c57893cce9e3d4 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1260,7 +1260,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	}
     
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index f1596412716726..c57893cce9e3d4 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1260,7 +1260,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	}
     
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
f441538893eb

drm/amdgpu: Use kvfree instead of kfree in amdgpu_gmc_get_nps_memranges()

2 files changed · +2 4
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index d9c7ad297293bd..2b37398337afc3 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1387,7 +1387,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	if (!*exp_ranges)
     		*exp_ranges = range_cnt;
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index d9c7ad297293bd..2b37398337afc3 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1387,7 +1387,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	if (!*exp_ranges)
     		*exp_ranges = range_cnt;
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
0c44d61945c4

drm/amdgpu: Use kvfree instead of kfree in amdgpu_gmc_get_nps_memranges()

2 files changed · +2 4
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index b793ce17140c41..d35d9719d56683 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1436,7 +1436,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	if (!*exp_ranges)
     		*exp_ranges = range_cnt;
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index b793ce17140c41..d35d9719d56683 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1436,7 +1436,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	if (!*exp_ranges)
     		*exp_ranges = range_cnt;
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
9ae85b0c1909

drm/amdgpu: Use kvfree instead of kfree in amdgpu_gmc_get_nps_memranges()

2 files changed · +2 4
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index aef1ba1bdca9e3..01ad5cc008a965 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1381,7 +1381,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	if (!*exp_ranges)
     		*exp_ranges = range_cnt;
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c+1 2 modified
    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    index aef1ba1bdca9e3..01ad5cc008a965 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
    @@ -1381,7 +1381,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
     	if (!*exp_ranges)
     		*exp_ranges = range_cnt;
     err:
    -	kfree(ranges);
    +	kvfree(ranges);
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Mismatched deallocator: memory allocated by kvcalloc() (which may use vmalloc()) is freed with kfree() instead of kvfree()."

Attack vector

An attacker does not directly trigger this bug; it is a kernel memory-management defect that manifests during normal GPU driver initialization. When `amdgpu_discovery_get_nps_info()` allocates the `ranges` array, `kvcalloc()` may fall back to `vmalloc()` for large allocations. The subsequent `kfree()` call in `amdgpu_gmc_get_nps_memranges()` is mismatched with the allocator, causing memory corruption when the freed memory was allocated by `vmalloc()` [patch_id=2662072]. No special network path or authentication is required — the bug occurs during standard amdgpu driver probe.

Affected code

The bug is in `drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c` in the function `amdgpu_gmc_get_nps_memranges()`. The function calls `amdgpu_discovery_get_nps_info()` which internally uses `kvcalloc()` to allocate the `ranges` array, but the error path and cleanup path used `kfree()` instead of `kvfree()` [patch_id=2662072][patch_id=2662079].

What the fix does

The patch replaces `kfree(ranges)` with `kvfree(ranges)` in the error path of `amdgpu_gmc_get_nps_memranges()` [patch_id=2662072][patch_id=2662079]. Since `amdgpu_discovery_get_nps_info()` allocates memory via `kvcalloc()`, which can return either `kmalloc` or `vmalloc` memory, the deallocation must use `kvfree()` to safely handle both cases. Using `kfree()` on `vmalloc`-backed memory leads to memory corruption.

Preconditions

  • configThe amdgpu kernel driver must be loaded and probe the GPU, triggering amdgpu_gmc_get_nps_memranges()
  • inputThe allocation from kvcalloc() must be large enough to fall back to vmalloc()

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

References

4

News mentions

0

No linked articles in our index yet.