udev_event_attach returns stale ENOMEM on the success path when the device dict already exists
| Field | Value |
|---|---|
| ID | DF-2806 |
| Status | new |
| Severity | Info |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:N |
| CWE | CWE-252 / erroneous status propagation |
| File | sys/kern/kern_udev.c |
| Lines | 589, 608-618 |
| Area | kern |
| Confidence | certain |
| Discovered | 2026-08-31 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | base:kern |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
udev_event_attach() initializes error = ENOMEM. In the non-alias branch, if udev_get_dict() returns a non-NULL dict on the first iteration the init loop body never runs, error is never reset, and the function returns ENOMEM after successfully queueing the ATTACH event. Current callers ignore the return; any future caller checking it would mis-handle every re-attach. Fix: error = 0 at :589, ENOMEM only on explicit failures.
Timeline
- 2026-08-31 Discovered during pass-2 audit of kern_udev.c (GLM 5.3).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2806 Β· 10 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 748 B | β raw | |
| VERDICT.md | β | 788 B | β raw | |
| build.sh | β | 50 B | view raw | |
| env.txt | β | 509 B | view raw | |
| fix.diff | β | 567 B | view raw | |
| h41.c | β | 14.9 KB | view raw | |
| harness.log | β | 2.0 KB | view raw | |
| manifest.json | β | 509 B | view raw | |
| run.sh | β | 104 B | view raw | |
| verdict.json | β | 1.9 KB | view raw |
DF-2806 β udev_event_attach stale ENOMEM on success (Info-tier hardening verification)
What
udev_event_attach stale ENOMEM on success
Build
cd /root/h41 && make
Run
kldload ./h41.ko; sysctl -w debug.h41.cmd=4
Expected
baseline (stock kernel): see verdict below fix kernel (all-41-fixes build): the bad behavior is gone
A/B one-liner: baseline: ret 12 ENOMEM | fix: ret 0
Files
README.md VERDICT.md build.sh env.txt fix.diff h41.c harness.log manifest.json run.sh verdict.json
Shared harness: h41.c (combined KLD, sysctl debug.h41.cmd=N driven).
Full batch context: the fix kernel contains all 41 hardening fixes of
this batch compiled together (build RC=0) and passed the complete A/B
suite plus a clean reboot.
DF-2806 β VERDICT
status: reproduced | reproduced: 1 | impact: none | confidence: certain
Mechanically reproduced via the harness on the stock guest: make_dev() creates the cdev and the devfs worker installs its udev dict (devfs_core.c:1428); a direct udev_event_attach(dev, NULL, 0) on that dev takes the non-alias branch whose while-loop body never runs (udict != NULL on entry), so the function returns the initialized error value ENOMEM (kern_udev.c:589) AFTER successfully queuing the ATTACH event - harness T5 observed return 12 on a fully successful re-attach. Current callers ignore the return (devfs_core.c:1428). On the fix kernel T5 returns 0.
Baseline vs fix kernel
baseline: baseline: ret 12 ENOMEM | fix: ret 0 fix: behavior changed as designed (see verdict)
Fix verification
fixedA/B: baseline return 12; fix kernel return 0 (error=0 init, ENOMEM only on explicit failures).
Confirmed kernel references
Detail
Evidence (decisive lines)
harness.log T5: returned 12 (ENOMEM) on success; fix kernel T5: 0
PoC changes
harness needed a 2s wait for the async devfs worker before the re-attach call - the first attempt raced dict creation
Verified recommended fix
Initialize error to 0 and set ENOMEM only on explicit failure paths
Verdict
Mechanically reproduced via the harness on the stock guest: make_dev() creates the cdev and the devfs worker installs its udev dict (devfs_core.c:1428); a direct udev_event_attach(dev, NULL, 0) on that dev takes the non-alias branch whose while-loop body never runs (udict != NULL on entry), so the function returns the initialized error value ENOMEM (kern_udev.c:589) AFTER successfully queuing the ATTACH event - harness T5 observed return 12 on a fully successful re-attach. Current callers ignore the return (devfs_core.c:1428). On the fix kernel T5 returns 0.
No comments yet.