β¬’ 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 1.0 KB ↓ raw
build.sh build-script N/A (source-only) 65 B view raw
run.sh run-script N/A (source-only) 89 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 status (batch validation)

Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.

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)