β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-1864

Missing braces in drm_sched_entity_init loop silently drops -ENOMEM, leaving partially-initialized sched entities

Field Value
ID DF-1864
Status new
Severity Low
CVSS 3.1 CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:L
CWE CWE-670 Always-Incorrect Control Flow Implementation
File sys/dev/drm/amd/amdgpu/amdgpu_ctx.c
Lines 174-178
Area dev/drm/amd (GPU context entity init)
Confidence likely
Discovered 2026-07-20
Reported pending
Known CVE none
CVE match dfly_specific

Summary

In amdgpu_ctx_init the body of the inner for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) loop is a single unbraced statement r = drm_sched_entity_init(...). The if (r) goto error_cleanup_entities; that follows is therefore OUTSIDE the loop. If any entity init except the LAST one fails (-ENOMEM from drm_sched_entity_init), the error is silently overwritten by the next iteration and the ctx is returned fully "initialized" with a partially-init sched entity whose rq_list is NULL and whose job_queue was never spsc_queue_init'd.

Root cause

amdgpu_ctx.c:174-178:

for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j)
    r = drm_sched_entity_init(&ctx->entities[i][j].entity,
                  rqs, num_rings, &ctx->guilty);
if (r)
    goto error_cleanup_entities;

The intent was for(j){ r=...; if(r) goto err; }. Without braces, only the assignment is looped; if (r) runs once after the loop with r = the LAST iteration's return code. drm_sched_entity_init (sched_entity.c:48-79) returns -ENOMEM when its kcalloc of rq_list fails; it has already done memset(entity,0,...), INIT_LIST_HEAD, and set entity->rq = rq_list[0] before failing, so the entity looks half-alive. The error path is never taken.

Threat model & preconditions

  • Attacker position: local user with render-node access triggering AMDGPU_CTX_OP_ALLOC_CTX under severe memory pressure.
  • Privileges gained or impact: kernel oops/panic in drm_sched_entity_destroy at teardown (sched_entity.c:302-305 β†’ drm_sched_entity_fini at :263 dereferencing rq->sched and calling drm_sched_rq_remove_entity on a never-added entity). The failed entity has no job_queue so it cannot be used to push jobs. Local DoS under memory pressure.
  • Required config or capabilities: device amdgpu; render node access.
  • Reachability: allocate ctx under OOM so one inner drm_sched_entity_init fails but the last one succeeds.

Add braces so each iteration's return code is checked.

--- a/sys/dev/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/sys/dev/drm/amd/amdgpu/amdgpu_ctx.c
@@ -171,9 +171,12 @@
            break;
        }

-       for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j)
-           r = drm_sched_entity_init(&ctx->entities[i][j].entity,
-                         rqs, num_rings, &ctx->guilty);
+       for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
+           r = drm_sched_entity_init(&ctx->entities[i][j].entity,
+                         rqs, num_rings, &ctx->guilty);
+           if (r)
+               goto error_cleanup_entities;
+       }
    }

Timeline

  • 2026-07-20 Discovered during automated audit.
  • 2026-07-20 Reported to DragonFlyBSD security contact (pending).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1864 Β· 4 files
FileTypeDescriptionSize
fix.diff suggested-fix git-apply-able fix for the cited bug 596 B view raw
VERDICT.md verdict source-confirmation analysis 715 B ↓ raw
build.sh build-script N/A (source-only) 61 B view raw
run.sh run-script N/A (source-only) 87 B view raw
VERDICT.md verdict source-confirmation analysis
↓ download raw

DF-1864 VERDICT

Verdict: REPRODUCED (source-confirmed)

Impact: Low (driver-level NULL deref / OOB / leak / DoS β€” hardware-gated)

Mechanism: amdgpu_ctx_init L174-178 for(j=0;j<amdgpu_ctx_num_entities[i];++j) r=drm_sched_entity_init(...); single unbraced statement. if(r) goto error_cleanup_entities at next line is OUTSIDE loop runs once wit

Citation: sys/dev/drm/amd/amdgpu/amdgpu_ctx.c:174-178

Fix: Applied fix.diff β€” compiles in batch kernel build (rc=0, -Werror).

Verification method: Source-only line-by-line trace of cited path:line. Low-severity driver bug; PoC trigger requires specific hardware or root context. Confirmed the cited vulnerable pattern exists in source.

Fix verification

fixed
baseline reproduced→ patch + rebuild →patched clean

fix.diff compiled in batch kernel build rc=0 -Werror

fix.diff compiled in batch kernel build rc=0 -Werror
↓ fix.diffcombined build rc=0

Confirmed kernel references

β€”

Detail

Exploit chain

none (Low severity)

Evidence (decisive lines)

Source-confirmed: missing braces drops error check outside loop (amdgpu_ctx.c:174-178)

Verified recommended fix

Source-confirmed: missing braces drops error check outside loop (amdgpu_ctx.c:174-178)

Verdict

Source-confirmed: missing braces drops error check outside loop (amdgpu_ctx.c:174-178)