Unchecked kzalloc failure in i915 MST fake-encoder init leads to NULL-deref panic on hub plug-in
| Field | Value |
|---|---|
| ID | DF-1856 |
| 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:H |
| CWE | CWE-690 Unchecked Return Value to NULL Pointer Dereference |
| File | sys/dev/drm/i915/intel_dp_mst.c |
| Lines | 541, 580-581, 595 |
| Area | dev/drm/i915 (MST encoder init) |
| Confidence | likely |
| Discovered | 2026-07-20 |
| Reported | pending |
| Known CVE | none |
| CVE match | dfly_specific |
Summary
intel_dp_create_fake_mst_encoder returns NULL on kzalloc failure (line 543),
but intel_dp_create_fake_mst_encoders stores that NULL into
intel_dp->mst_encoders[pipe] (line 580) and unconditionally returns true
(line 581). intel_dp_mst_encoder_init ignores the return value (line 595) and
proceeds to enable MST. Any later dereference of
intel_dp->mst_encoders[pipe]->base.base in intel_mst_atomic_best_encoder
(line 407) or intel_dp_add_mst_connector (line 471) then NULL-dereferences,
panicking the kernel.
Root cause
intel_dp_create_fake_mst_encoder (intel_dp_mst.c:534-570):
intel_mst = kzalloc(sizeof(*intel_mst), GFP_KERNEL);
if (!intel_mst)
return NULL; /* line 543-544 */
The caller intel_dp_create_fake_mst_encoders (lines 572-582) does NOT check
the per-pipe return:
for_each_pipe(dev_priv, pipe)
intel_dp->mst_encoders[pipe] = intel_dp_create_fake_mst_encoder(intel_dig_port, pipe);
return true; /* line 580-581 */
The next-level caller intel_dp_mst_encoder_init (lines 584-603) does:
intel_dp_create_fake_mst_encoders(intel_dig_port); /* return discarded, line 595 */
and unconditionally proceeds to drm_dp_mst_topology_mgr_init, marking MST as
enabled. When a sink/hub is later attached, intel_dp_add_mst_connector at line
469-476 computes &intel_dp->mst_encoders[pipe]->base.base which is
&((struct intel_dp_mst_encoder *)NULL)->base.base β a small constant address.
The subsequent drm_connector_attach_encoder dereference faults.
Likewise intel_mst_atomic_best_encoder (lines 400-408) dereferences
intel_dp->mst_encoders[crtc->pipe]->base.base (line 407) on every atomic
modeset request involving the MST connector.
Threat model & preconditions
- Attacker position: local user who can drive the system into memory pressure during the i915 driver probe / MST initialization window, then trigger a DisplayPort MST hub plug-in event (or trigger one programmatically via DRM modeset ioctls).
- Privileges gained or impact: local denial of service (kernel panic). No privilege escalation, no info leak β availability impact only.
- Required config or capabilities: Intel i915 hardware with MST support compiled in (default). Memory pressure precondition (fork-bomb, hugepage exhaustion, large shm allocations) during driver load.
- Reachability: OOM during probe leaves NULL encoder slots; MST hub plug-in or atomic modeset on the MST connector dereferences them.
Proof of concept
/* mem_pressure.c β drive system into OOM during i915 probe */
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
int main(void){
void *p;
while ((p = mmap(NULL, 1UL<<20, PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, -1, 0)) != MAP_FAILED) {
memset(p, 0x55, 1UL<<20);
}
pause(); /* hold the pressure while i915 probe runs */
return 0;
}
Build & run
cc -O2 mem_pressure.c -o mem_pressure # Run mem_pressure in background, then trigger i915 probe (boot, kldload, # or hot-add). Plug in a DisplayPort MST hub.
Expected output
Fatal trap 12: page fault while in kernel mode faulting address near offsetof(struct intel_dp_mst_encoder, base.base) β 0 intel_dp_add_mst_connector+0x.. at 0x..
Impact
Low-severity (narrow trigger) local DoS. Requires OOM during probe + MST hub plug-in. No escalation primitive.
Recommended fix
Make intel_dp_create_fake_mst_encoders propagate allocation failure and have
intel_dp_mst_encoder_init bail out.
--- a/sys/dev/drm/i915/intel_dp_mst.c
+++ b/sys/dev/drm/i915/intel_dp_mst.c
@@ -572,11 +572,18 @@ static struct intel_dp_mst_encoder *
static bool
intel_dp_create_fake_mst_encoders(struct intel_digital_port *intel_dig_port)
{
struct intel_dp *intel_dp = &intel_dig_port->dp;
struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
enum i915_pipe pipe;
+ int i;
- for_each_pipe(dev_priv, pipe)
- intel_dp->mst_encoders[pipe] = intel_dp_create_fake_mst_encoder(intel_dig_port, pipe);
- return true;
+ for_each_pipe(dev_priv, pipe) {
+ intel_dp->mst_encoders[pipe] = intel_dp_create_fake_mst_encoder(intel_dig_port, pipe);
+ if (!intel_dp->mst_encoders[pipe]) {
+ for (i = 0; i < pipe; i++)
+ intel_dp_mst_encoder_destroy(&intel_dp->mst_encoders[i]->base);
+ return false;
+ }
+ }
+ return true;
}
@@ -590,8 +597,12 @@ int
struct intel_dp *intel_dp = &intel_dig_port->dp;
struct drm_device *dev = intel_dig_port->base.base.dev;
int ret;
intel_dp->can_mst = true;
intel_dp->mst_mgr.cbs = &mst_cbs;
- /* create encoders */
- intel_dp_create_fake_mst_encoders(intel_dig_port);
+ /* create encoders */
+ if (!intel_dp_create_fake_mst_encoders(intel_dig_port)) {
+ intel_dp->can_mst = false;
+ return -ENOMEM;
+ }
ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, dev,
&intel_dp->aux, 16, 3, conn_base_id);
Timeline
- 2026-07-20 Discovered during automated audit.
- 2026-07-20 Reported to DragonFlyBSD security contact (pending).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1856 Β· 4 files| File | Type | Description | Size | |
|---|---|---|---|---|
| fix.diff | suggested-fix | git-apply-able fix for the cited bug | 515 B | view raw |
| VERDICT.md | verdict | source-confirmation analysis | 711 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 |
DF-1856 VERDICT
Verdict: REPRODUCED (source-confirmed)
Impact: Low (driver-level NULL deref / OOB / leak / DoS β hardware-gated)
Mechanism: intel_dp_create_fake_mst_encoder L541 kzalloc(sizeof(*intel_mst),GFP_KERNEL) if(!intel_mst) return NULL L543-544. Caller intel_dp_create_fake_mst_encoders L579-581 for_each_pipe intel_dp->mst_encoders
Citation: sys/dev/drm/i915/intel_dp_mst.c:541-595
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
fixedfix.diff compiled in batch kernel build rc=0 -Werror
fix.diff compiled in batch kernel build rc=0 -Werror
Confirmed kernel references
β
Detail
Exploit chain
none (Low severity)
Evidence (decisive lines)
Source-confirmed: unchecked kzalloc failure in i915 MST fake-encoder init (intel_dp_mst.c:541-595)
Verified recommended fix
Source-confirmed: unchecked kzalloc failure in i915 MST fake-encoder init (intel_dp_mst.c:541-595)
Verdict
Source-confirmed: unchecked kzalloc failure in i915 MST fake-encoder init (intel_dp_mst.c:541-595)
No comments yet.