# DF-4879 — unchecked `drm_mode_create_standard_properties()` in `drm_mode_config_init()`

**File:** `sys/dev/drm/drm_mode_config.c` (pass 2)
**Severity:** Low (kernel NULL-deref panic, setup-gated)
**Status:** source-proven, NOT PoC-verified on this guest (see VERDICT.md)

## Summary

`drm_mode_config_init()` (sys/dev/drm/drm_mode_config.c:370) calls
`drm_mode_create_standard_properties(dev)` at line 392 and **discards its
return value**. That helper performs ~20 sequential allocations
(drm_mode_config.c:217-355) and returns `-ENOMEM` on the first failure,
leaving `dev->mode_config.prop_fb_id / prop_crtc_id / prop_crtc_x..h /
prop_active / prop_mode_id / prop_src_x..h / ...` NULL (only the earlier
ones are set).

Driver load then continues with half-initialized mode_config:
`drm_universal_plane_init()` attaches those (possibly NULL) property
pointers to **every** plane (drm_plane.c:262-275:
`drm_object_attach_property(&plane->base, config->prop_fb_id, 0)` … — no
NULL check), and `drm_crtc_init_with_planes()` attaches
`config->prop_active` / `config->prop_mode_id` (drm_crtc.c:339-341).

Any later unprivileged ioctl that enumerates object properties —
`DRM_IOCTL_MODE_OBJ_GETPROPERTIES` (drm_ioctl.c:678, `DRM_UNLOCKED |
DRM_RENDER_ALLOW`, no auth) or `DRM_IOCTL_MODE_GETCONNECTOR`
(drm_connector.c:1820) — walks the property array and dereferences
`prop->flags` with no NULL check (drm_mode_object.c:341-346) → kernel
NULL-deref → panic.

## Preconditions / honesty

* The NULL-prop state requires `-ENOMEM` during driver load
  (root-triggered setup: kldload/boot-time memory pressure). i915,
  radeon and amdgpu all ignore the (void) init result today
  (intel_display.c:15342, radeon_display.c:1579, amdgpu_device.c:2604).
* Once the device is in that state, the panic trigger is a plain
  unprivileged ioctl on /dev/dri/card0 or /dev/dri/renderD128.
* Inherited from Linux (~4.19 `drm_mode_config_init`); upstream later
  fixed the class by moving to `drmm_mode_config_init()` which fails
  the whole device init. DragonFly port kept the void variant.
* Derefs are reads only (`prop->flags`, `prop->base.id`) — no write
  primitive, no kernel info leak (page-0 mapping would only read back
  attacker-crafted bytes). Impact ceiling: local DoS/panic.

## Why untested here

The audit QEMU guest has **no DRM device** (`/dev/dri` absent — QEMU VGA,
no i915/radeon/amdgpu binding), so `DRM_IOCTL_MODE_OBJ_GETPROPERTIES`
cannot even be issued; and the ENOMEM-at-load precondition cannot be
injected without kernel fault-injection knobs this guest does not have.
The chain is verified line-by-line in source instead (VERDICT.md).

## Contents

* `VERDICT.md` — full narrative with path:line evidence
* `trigger.c` — reference prober (would exercise the deref if a
  NULL-prop device existed; NOT runnable on this guest)
* `build.sh` — cc command for trigger.c
* `fix.diff` — propagate the failure (git-apply-able, never applied to sys/)
* `verdict.json` / `manifest.json`
