CVE-2026-46218
Description
In the Linux kernel, the following vulnerability has been resolved:
drm/amdgpu: Add bounds checking to ib_{get,set}_value
The uvd/vce/vcn code accesses the IB at predefined offsets without checking that the IB is large enough. Check the bounds here. The caller is responsible for making sure it can handle arbitrary return values.
Also make the idx a uint32_t to prevent overflows causing the condition to fail.
Affected products
1Patches
10ee26fcf7c5cfdrm/amdgpu: Add bounds checking to ib_{get,set}_value
1 file changed · +7 −5
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h+7 −5 modifieddiff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index cb0fb1a989d2f5..14fd31d3437a85 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -553,15 +553,18 @@ void amdgpu_debugfs_ring_init(struct amdgpu_device *adev, int amdgpu_ring_init_mqd(struct amdgpu_ring *ring); -static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, int idx) +static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, uint32_t idx) { - return ib->ptr[idx]; + if (idx < ib->length_dw) + return ib->ptr[idx]; + return 0; } -static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, int idx, +static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, uint32_t idx, uint32_t value) { - ib->ptr[idx] = value; + if (idx < ib->length_dw) + ib->ptr[idx] = value; } int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, -- cgit 1.3-korg
a853178d23e7drm/amdgpu: Add bounds checking to ib_{get,set}_value
1 file changed · +7 −5
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h+7 −5 modifieddiff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 9af2cda676ad7e..3eb74f84578021 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -471,15 +471,18 @@ void amdgpu_debugfs_ring_init(struct amdgpu_device *adev, int amdgpu_ring_init_mqd(struct amdgpu_ring *ring); -static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, int idx) +static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, uint32_t idx) { - return ib->ptr[idx]; + if (idx < ib->length_dw) + return ib->ptr[idx]; + return 0; } -static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, int idx, +static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, uint32_t idx, uint32_t value) { - ib->ptr[idx] = value; + if (idx < ib->length_dw) + ib->ptr[idx] = value; } int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, -- cgit 1.3-korg
fec8b11b55e5drm/amdgpu: Add bounds checking to ib_{get,set}_value
1 file changed · +7 −5
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h+7 −5 modifieddiff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 4b46e3c26ff39f..0098b1eadfc878 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -547,15 +547,18 @@ void amdgpu_debugfs_ring_init(struct amdgpu_device *adev, int amdgpu_ring_init_mqd(struct amdgpu_ring *ring); -static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, int idx) +static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, uint32_t idx) { - return ib->ptr[idx]; + if (idx < ib->length_dw) + return ib->ptr[idx]; + return 0; } -static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, int idx, +static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, uint32_t idx, uint32_t value) { - ib->ptr[idx] = value; + if (idx < ib->length_dw) + ib->ptr[idx] = value; } int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, -- cgit 1.3-korg
66085e206431drm/amdgpu: Add bounds checking to ib_{get,set}_value
1 file changed · +7 −5
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h+7 −5 modifieddiff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index ce5af137ee400e..715c9e43e13aa4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -559,15 +559,18 @@ void amdgpu_debugfs_ring_init(struct amdgpu_device *adev, int amdgpu_ring_init_mqd(struct amdgpu_ring *ring); -static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, int idx) +static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, uint32_t idx) { - return ib->ptr[idx]; + if (idx < ib->length_dw) + return ib->ptr[idx]; + return 0; } -static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, int idx, +static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, uint32_t idx, uint32_t value) { - ib->ptr[idx] = value; + if (idx < ib->length_dw) + ib->ptr[idx] = value; } int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, -- cgit 1.3-korg
0fb5cb556b24drm/amdgpu: Add bounds checking to ib_{get,set}_value
1 file changed · +7 −5
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h+7 −5 modifieddiff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 60f770b99c2c54..dc17e2ce84d075 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -440,15 +440,18 @@ void amdgpu_debugfs_ring_init(struct amdgpu_device *adev, int amdgpu_ring_init_mqd(struct amdgpu_ring *ring); -static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, int idx) +static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, uint32_t idx) { - return ib->ptr[idx]; + if (idx < ib->length_dw) + return ib->ptr[idx]; + return 0; } -static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, int idx, +static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, uint32_t idx, uint32_t value) { - ib->ptr[idx] = value; + if (idx < ib->length_dw) + ib->ptr[idx] = value; } int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, -- cgit 1.3-korg
66085e206431drm/amdgpu: Add bounds checking to ib_{get,set}_value
1 file changed · +7 −5
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h+7 −5 modifieddiff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index ce5af137ee400e..715c9e43e13aa4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -559,15 +559,18 @@ void amdgpu_debugfs_ring_init(struct amdgpu_device *adev, int amdgpu_ring_init_mqd(struct amdgpu_ring *ring); -static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, int idx) +static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, uint32_t idx) { - return ib->ptr[idx]; + if (idx < ib->length_dw) + return ib->ptr[idx]; + return 0; } -static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, int idx, +static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, uint32_t idx, uint32_t value) { - ib->ptr[idx] = value; + if (idx < ib->length_dw) + ib->ptr[idx] = value; } int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, -- cgit 1.3-korg
ee26fcf7c5cfdrm/amdgpu: Add bounds checking to ib_{get,set}_value
1 file changed · +7 −5
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h+7 −5 modifieddiff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index cb0fb1a989d2f5..14fd31d3437a85 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -553,15 +553,18 @@ void amdgpu_debugfs_ring_init(struct amdgpu_device *adev, int amdgpu_ring_init_mqd(struct amdgpu_ring *ring); -static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, int idx) +static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, uint32_t idx) { - return ib->ptr[idx]; + if (idx < ib->length_dw) + return ib->ptr[idx]; + return 0; } -static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, int idx, +static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, uint32_t idx, uint32_t value) { - ib->ptr[idx] = value; + if (idx < ib->length_dw) + ib->ptr[idx] = value; } int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, -- cgit 1.3-korg
a853178d23e7drm/amdgpu: Add bounds checking to ib_{get,set}_value
1 file changed · +7 −5
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h+7 −5 modifieddiff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 9af2cda676ad7e..3eb74f84578021 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -471,15 +471,18 @@ void amdgpu_debugfs_ring_init(struct amdgpu_device *adev, int amdgpu_ring_init_mqd(struct amdgpu_ring *ring); -static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, int idx) +static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, uint32_t idx) { - return ib->ptr[idx]; + if (idx < ib->length_dw) + return ib->ptr[idx]; + return 0; } -static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, int idx, +static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, uint32_t idx, uint32_t value) { - ib->ptr[idx] = value; + if (idx < ib->length_dw) + ib->ptr[idx] = value; } int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, -- cgit 1.3-korg
fec8b11b55e5drm/amdgpu: Add bounds checking to ib_{get,set}_value
1 file changed · +7 −5
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h+7 −5 modifieddiff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 4b46e3c26ff39f..0098b1eadfc878 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -547,15 +547,18 @@ void amdgpu_debugfs_ring_init(struct amdgpu_device *adev, int amdgpu_ring_init_mqd(struct amdgpu_ring *ring); -static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, int idx) +static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, uint32_t idx) { - return ib->ptr[idx]; + if (idx < ib->length_dw) + return ib->ptr[idx]; + return 0; } -static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, int idx, +static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, uint32_t idx, uint32_t value) { - ib->ptr[idx] = value; + if (idx < ib->length_dw) + ib->ptr[idx] = value; } int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, -- cgit 1.3-korg
0fb5cb556b24drm/amdgpu: Add bounds checking to ib_{get,set}_value
1 file changed · +7 −5
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h+7 −5 modifieddiff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 60f770b99c2c54..dc17e2ce84d075 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -440,15 +440,18 @@ void amdgpu_debugfs_ring_init(struct amdgpu_device *adev, int amdgpu_ring_init_mqd(struct amdgpu_ring *ring); -static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, int idx) +static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, uint32_t idx) { - return ib->ptr[idx]; + if (idx < ib->length_dw) + return ib->ptr[idx]; + return 0; } -static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, int idx, +static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, uint32_t idx, uint32_t value) { - ib->ptr[idx] = value; + if (idx < ib->length_dw) + ib->ptr[idx] = value; } int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing bounds checking in amdgpu_ib_get_value and amdgpu_ib_set_value allows out-of-bounds array access."
Attack vector
An attacker can submit a crafted command buffer (IB) to the UVD, VCE, or VCN hardware blocks via the DRM/amdgpu interface. The uvd/vce/vcn code accesses the IB at predefined offsets using `amdgpu_ib_get_value` and `amdgpu_ib_set_value` without checking that the IB is large enough [patch_id=2897665]. By supplying an IB smaller than the expected offset, the attacker causes an out-of-bounds read or write on the kernel heap, which can lead to memory corruption or information disclosure. The `idx` parameter was previously a signed `int`, allowing negative values or integer overflows to bypass any implicit checks.
Affected code
The vulnerability resides in the inline helper functions `amdgpu_ib_get_value` and `amdgpu_ib_set_value` defined in `drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h` [patch_id=2897665]. These functions directly index into `ib->ptr[idx]` without first verifying that `idx` is within the bounds of `ib->length_dw`.
What the fix does
The patch adds a bounds check to both `amdgpu_ib_get_value` and `amdgpu_ib_set_value` so that the array index `idx` is compared against `ib->length_dw` before accessing `ib->ptr[idx]` [patch_id=2897665]. If `idx` is out of bounds, `amdgpu_ib_get_value` returns 0 and `amdgpu_ib_set_value` silently discards the write. The `idx` parameter type is also changed from signed `int` to `uint32_t` to prevent negative values or integer overflows from defeating the bounds check. The commit message notes that callers must be prepared to handle arbitrary return values from the getter.
Preconditions
- inputThe attacker must be able to submit a command buffer (IB) to the UVD, VCE, or VCN hardware engines via the DRM/amdgpu ioctl interface.
- inputThe submitted IB must be smaller than the predefined offset that the uvd/vce/vcn code expects to access.
Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/0fb5cb556b249b2b64c0f818136c4c3e838ef53fnvd
- git.kernel.org/stable/c/66085e206431ef88ce36f53c1f53d570790ccc9envd
- git.kernel.org/stable/c/a853178d23e774adfe3a35073c375b04b3b20f7dnvd
- git.kernel.org/stable/c/ee26fcf7c5cf131f0b6a732faa27d79ec61b8ec7nvd
- git.kernel.org/stable/c/fec8b11b55e53ff51a741e56894fe331a516f5c6nvd
News mentions
0No linked articles in our index yet.