Uninitialized mode_cmd stack fields propagated into long-lived drm_framebuffer (amdgpu)
- File:
sys/dev/drm/amd/amdgpu/amdgpu_fb.c - Lines: 213, 219β220, 225, 146, 248
- Severity: Low
- CVSS 3.1:
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U:C:L/I:N/A:N - CWE: CWE-457 Use of Uninitialized Variable
- Confidence: certain
- Status: new
- Related: DF-1971 (radeon_fb.c identical-class bug)
Summary
The stack-allocated struct drm_mode_fb_cmd2 mode_cmd; at line 213 is only
partially initialized. The remaining fields β pitches[1..3],
offsets[0..3], modifier[0..3], flags, handles[0..3], fb_id β contain
uninitialized stack garbage. These are copied verbatim into the long-lived
drm_framebuffer by drm_helper_mode_fill_fb_struct
(amdgpu_display.c:513 β drm_modeset_helper.c:88-92) and persist for the
framebuffer's lifetime.
Root cause
Line 213: struct drm_mode_fb_cmd2 mode_cmd; β stack-allocated, no initializer.
Explicitly set fields:
- mode_cmd.width = sizes->surface_width (line 219)
- mode_cmd.height = sizes->surface_height (line 220)
- mode_cmd.pixel_format = drm_mode_legacy_fb_format(...) (line 225-226)
- mode_cmd.pitches[0] = amdgpu_align_pitch(...) (line 146, inside create_pinned_object)
Uninitialized fields (stack garbage):
- mode_cmd.pitches[1], pitches[2], pitches[3]
- mode_cmd.offsets[0], offsets[1], offsets[2], offsets[3]
- mode_cmd.modifier[0], modifier[1], modifier[2], modifier[3]
- mode_cmd.flags
- mode_cmd.handles[0], handles[1], handles[2], handles[3]
- mode_cmd.fb_id
These are passed to amdgpu_display_framebuffer_init() (line 248-249) β
drm_helper_mode_fill_fb_struct() (amdgpu_display.c:513). That function
copies them directly into the drm_framebuffer (drm_modeset_helper.c:87-92):
for (i = 0; i < 4; i++) {
fb->pitches[i] = mode_cmd->pitches[i]; // copies garbage for i=1,2,3
fb->offsets[i] = mode_cmd->offsets[i]; // copies garbage for all i
}
fb->modifier = mode_cmd->modifier[0]; // copies garbage
fb->flags = mode_cmd->flags; // copies garbage
The fbdev framebuffer is long-lived (persists until driver unload).
Threat model
Minimal practical impact for the fbdev framebuffer (single-plane XRGB8888, so
pitches[1..3] and offsets[] are unused). The info leak is of kernel stack
contents into the drm_framebuffer's pitches/offsets/modifier fields,
which could be read back via DRM_IOCTL_MODE_GETFB2 by a DRM client.
The leaked bytes are stack garbage (not secrets in practice, but theoretically could contain prior function call residuals).
Severity is Low because the fbdev framebuffer is kernel-internal and not
directly exposed to user-mode ADDFB2-style queries.
Proof of concept
- Load amdgpu driver with a display connected (triggers
amdgpufb_create). - Open the DRM device.
- Use
DRM_IOCTL_MODE_GETFB(orGETFB2) on the fbdev framebuffer ID (obtained viaDRM_IOCTL_MODE_GETRESOURCES). - The returned
pitches[1..3],offsets[0..3],modifiervalues contain whatever was on the kernel stack at the timeamdgpufb_createran β typically zeros fromkzalloc'd stack pages, but could contain residual data from prior kernel function calls. - Success: non-zero values in secondary plane pitches/offsets that were never explicitly set.
Note: on DragonFly, DRM_IOCTL_MODE_GETFB may not be fully wired, limiting
exposure.
Recommended fix
Zero-initialize mode_cmd before use:
--- a/sys/dev/drm/amd/amdgpu/amdgpu_fb.c
+++ b/sys/dev/drm/amd/amdgpu/amdgpu_fb.c
@@ -213,6 +213,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
struct drm_mode_fb_cmd2 mode_cmd;
struct drm_gem_object *gobj = NULL;
struct amdgpu_bo *abo = NULL;
+ memset(&mode_cmd, 0, sizeof(mode_cmd));
int ret;
References
sys/dev/drm/amd/amdgpu/amdgpu_fb.c:213β uninitialized stackmode_cmdsys/dev/drm/amd/amdgpu/amdgpu_fb.c:219-225,146β partial initializationsys/dev/drm/amd/amdgpu/amdgpu_display.c:513βdrm_helper_mode_fill_fb_structcalledsys/dev/drm/drm_modeset_helper.c:87-92β copies all fields verbatim into long-livedfb
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1984 Β· 5 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | verdict | Source verification narrative | 1.2 KB | β raw |
| fix.diff | suggested-fix | Fix: Zero-initialize: struct drm_mode_fb_cmd2 mode_cmd = { 0 }; | 454 B | view raw |
| build.sh | build-script | Build/validation instructions | 366 B | view raw |
| run.sh | run-script | Run instructions (HW-gated, source-only) | 184 B | view raw |
| env.txt | environment | Guest environment | 404 B | view raw |
DF-1984 - Source Verification
Verdict: REPRODUCED (source-only confirmation)
Finding: sys/dev/drm/amd/amdgpu/amdgpu_fb.c:213
Mechanism: struct drm_mode_fb_cmd2 mode_cmd declared without initializer. Only width/height/pixel_format/pitches[0] written. pitches[1..3], offsets, modifier, flags, handles stay stack garbage β propagated into long-lived drm_framebuffer.
Hardware dependency: Requires amdgpu GPU.
Fix: Zero-initialize: struct drm_mode_fb_cmd2 mode_cmd = { 0 };
Verification method
Source-only confirmation. The cited code path was traced line-by-line in the audited sys/ tree. The bug exists exactly as described. This is a HW-gated driver finding β the vulnerable code path requires specific hardware (GPU, controller, PHY, TPM, etc.) not present in the QEMU audit guest. Runtime reproduction on this guest is not possible without the hardware.
Fix validation
fix.diff authored and applied to guest source. All 40 fixes in this batch
compile cleanly in a single combined kernel build: make -j6 nativekernel
KERNCONF=X86_64_GENERIC β rc=0, zero -Werror violations.
Kernel: DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026
Fix verification
not_testablenot_testable: HW-gated. fix.diff applies + compiles in batch build (rc=0 -Werror). Source trace confirms fix closes the path.
Batch build: 40 fix.diffs applied, make nativekernel β rc=0 -Werror. Bug at sys/dev/drm/amd/amdgpu/amdgpu_fb.c:213 source-confirmed.
Confirmed kernel references
- s
- y
- s
- /
- d
- e
- v
- /
- d
- r
- m
- /
- a
- m
- d
- /
- a
- m
- d
- g
- p
- u
- /
- a
- m
- d
- g
- p
- u
- _
- f
- b
- .
- c
- :
- 2
- 1
- 3
Detail
Exploit chain
none
Evidence (decisive lines)
Source trace sys/dev/drm/amd/amdgpu/amdgpu_fb.c:213. HW-gated (no HW in QEMU). Fix compiles in batch build rc=0.
PoC changes
Evidence pack: VERDICT.md, fix.diff, manifest.json. Fix: mode_cmd uninitialized β stack garbage in fb. Zero-initialize.
Verified recommended fix
See fix.diff. mode_cmd uninitialized β stack garbage in fb. Zero-initialize.
Verdict
REPRODUCED (source-only). sys/dev/drm/amd/amdgpu/amdgpu_fb.c:213: mode_cmd uninitialized β stack garbage in fb. Zero-initialize.
No comments yet.