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

CVE-2026-46006

CVE-2026-46006

Description

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

drm/nouveau: fix u32 overflow in pushbuf reloc bounds check

nouveau_gem_pushbuf_reloc_apply() validates each relocation with

if (r->reloc_bo_offset + 4 > nvbo->bo.base.size)

but reloc_bo_offset is __u32 (uapi/drm/nouveau_drm.h) and the integer literal 4 promotes to unsigned int, so the addition is performed in 32 bits and wraps before the comparison against the size_t bo size.

Cast to u64 so the addition happens in 64-bit arithmetic.

[ Add Fixes: tag. - Danilo ]

AI Insight

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

A 32-bit unsigned integer overflow in Nouveau's pushbuf relocation bounds check allows validation bypass leading to out-of-bounds write.

Vulnerability

In the Linux kernel's drm/nouveau driver, the nouveau_gem_pushbuf_reloc_apply() function validates relocation offsets with the check if (r->reloc_bo_offset + 4 > nvbo->bo.base.size). The field reloc_bo_offset is a __u32 from the UAPI (drm/nouveau_drm.h), and the literal 4 is an unsigned int. The addition is performed in 32-bit arithmetic, which can overflow if reloc_bo_offset is near 0xFFFFFFFF. This wraps the result to a small value, bypassing the size comparison against the size_t object size and allowing an out-of-bounds write. The vulnerability affects kernel versions before the fix commit 332884f5eb79 (stable). [1]

Exploitation

An attacker requires a user account with access to the Nouveau DRM device (usually requires local access or running as a user with sufficient privileges). By passing a crafted relocation entry with reloc_bo_offset set to a value close to the 32-bit maximum, the bounds check can be bypassed. The attacker also needs a buffer object of appropriate size. The sequence involves: 1) creating a GEM buffer, 2) submitting a push buffer with a relocation that has a carefully chosen offset to trigger the overflow, and 3) the kernel will then write relocation data beyond the intended buffer boundary.

Impact

On successful exploitation, an attacker can achieve an out-of-bounds write relative to the buffer object. This can corrupt kernel memory, potentially leading to privilege escalation, denial of service, or information disclosure. The vulnerability has a high CVSS score of 7.8 (CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H), indicating local privilege escalation potential. [1]

Mitigation

The fix was included in Linux kernel stable commit 332884f5eb79 (dated 2026-05-27). Users should update to a kernel version containing this commit or later. Distributions that backport stable patches will have the fix in their respective kernel packages. No known workaround exists other than applying the patch. The vulnerability is not listed in CISA's Known Exploited Vulnerabilities (KEV) catalog at the time of publication.

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

1
  • Linux/Kernelllm-fuzzy
    Range: affected versions prior to the stable commit fixes

Patches

10
e441d5c23ec6

drm/nouveau: fix u32 overflow in pushbuf reloc bounds check

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitGreg Kroah-HartmanApr 20, 2026Fixed in 7.0.4via kernel-cna
2 files changed · +2 4
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 82621ede42e1ec..20dba02d6175bc 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 82621ede42e1ec..20dba02d6175bc 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
fa297e919d16

drm/nouveau: fix u32 overflow in pushbuf reloc bounds check

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitGreg Kroah-HartmanApr 20, 2026Fixed in 6.6.140via kernel-cna
2 files changed · +2 4
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index cd97df6903352c..e8ce33c89548d0 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -679,7 +679,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index cd97df6903352c..e8ce33c89548d0 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -679,7 +679,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
d749a9a0ee40

drm/nouveau: fix u32 overflow in pushbuf reloc bounds check

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitGreg Kroah-HartmanApr 20, 2026Fixed in 6.12.86via kernel-cna
2 files changed · +2 4
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 67e3c99de73ae6..1771fe338f8d68 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 67e3c99de73ae6..1771fe338f8d68 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
332884f5eb79

drm/nouveau: fix u32 overflow in pushbuf reloc bounds check

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitGreg Kroah-HartmanApr 20, 2026Fixed in 6.18.27via kernel-cna
2 files changed · +2 4
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 690e10fbf0bd65..f6cfb6ea4885d9 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 690e10fbf0bd65..f6cfb6ea4885d9 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
2fc87d37be1b

drm/nouveau: fix u32 overflow in pushbuf reloc bounds check

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitGreg Kroah-HartmanApr 20, 2026Fixed in 7.1-rc1via kernel-cna
2 files changed · +2 4
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 82621ede42e1ec..20dba02d6175bc 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 82621ede42e1ec..20dba02d6175bc 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
332884f5eb79

drm/nouveau: fix u32 overflow in pushbuf reloc bounds check

2 files changed · +2 4
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 690e10fbf0bd65..f6cfb6ea4885d9 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 690e10fbf0bd65..f6cfb6ea4885d9 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
e441d5c23ec6

drm/nouveau: fix u32 overflow in pushbuf reloc bounds check

2 files changed · +2 4
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 82621ede42e1ec..20dba02d6175bc 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 82621ede42e1ec..20dba02d6175bc 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
fa297e919d16

drm/nouveau: fix u32 overflow in pushbuf reloc bounds check

2 files changed · +2 4
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index cd97df6903352c..e8ce33c89548d0 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -679,7 +679,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index cd97df6903352c..e8ce33c89548d0 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -679,7 +679,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
d749a9a0ee40

drm/nouveau: fix u32 overflow in pushbuf reloc bounds check

2 files changed · +2 4
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 67e3c99de73ae6..1771fe338f8d68 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 67e3c99de73ae6..1771fe338f8d68 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
2fc87d37be1b

drm/nouveau: fix u32 overflow in pushbuf reloc bounds check

2 files changed · +2 4
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 82621ede42e1ec..20dba02d6175bc 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/nouveau/nouveau_gem.c+1 2 modified
    diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
    index 82621ede42e1ec..20dba02d6175bc 100644
    --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
    +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
    @@ -686,7 +686,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
     		}
     		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
     
    -		if (unlikely(r->reloc_bo_offset + 4 >
    +		if (unlikely((u64)r->reloc_bo_offset + 4 >
     			     nvbo->bo.base.size)) {
     			NV_PRINTK(err, cli, "reloc outside of bo\n");
     			ret = -EINVAL;
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Integer overflow in bounds check: `r->reloc_bo_offset` is `__u32` and the addition with the integer literal `4` wraps in 32-bit arithmetic before comparison against the `size_t` buffer object size, allowing an out-of-bounds relocation to pass validation."

Attack vector

An attacker with access to the Nouveau DRM device submits a pushbuf relocation where `reloc_bo_offset` is set to a value near `UINT32_MAX` (e.g. `0xFFFFFFFC` or larger). The expression `r->reloc_bo_offset + 4` wraps to a small value in 32-bit unsigned arithmetic, bypassing the bounds check against `nvbo->bo.base.size` [patch_id=2660490]. The kernel then applies the relocation at the attacker-controlled offset, which can be outside the buffer object, leading to out-of-bounds memory access. No special privileges beyond DRM file descriptor access are required.

Affected code

The vulnerable code is in `drivers/gpu/drm/nouveau/nouveau_gem.c` in the function `nouveau_gem_pushbuf_reloc_apply()`, specifically at the bounds check `if (unlikely(r->reloc_bo_offset + 4 > nvbo->bo.base.size))` [patch_id=2660490]. The field `r->reloc_bo_offset` is defined as `__u32` in the UAPI header `uapi/drm/nouveau_drm.h`.

What the fix does

The patch casts `r->reloc_bo_offset` to `u64` before adding 4, so the addition is performed in 64-bit arithmetic and cannot wrap [patch_id=2660490]. This ensures that a large offset like `0xFFFFFFFC` remains large after the addition and correctly fails the `> nvbo->bo.base.size` check. The single-line change in `drivers/gpu/drm/nouveau/nouveau_gem.c` at the bounds check in `nouveau_gem_pushbuf_reloc_apply()` is the complete fix.

Preconditions

  • authAttacker must have access to the Nouveau DRM device (e.g., /dev/dri/card*).
  • inputAttacker must be able to submit a NOUVEAU_GEM_PUSHBUF ioctl with a crafted relocation entry containing a reloc_bo_offset value near UINT32_MAX.

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

References

5

News mentions

0

No linked articles in our index yet.