vga_switcheroo_write uses negative errno return convention inconsistent with BSD dev_write
- File:
sys/dev/video/vga/vga_switcheroo.c - Lines: 1112, 1113, 1114, 1221
- Severity: Info
- CVSS:
CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U:C:N/I:N/A:N - CWE: CWE-440 Expected Behavior Violation
- Confidence: certain
Summary
vga_switcheroo_write() assigns error = -EINVAL; (negative) and returns it.
DragonFlyBSD dev_write contract returns 0 on success or a positive errno on
failure; the kernel's dev_dwrite wrapper and the syscall path interpret a
negative return inconsistently, so writing to /dev/vga_switcheroo when
vga_switcheroo is not active returns a garbage error code to userspace rather
than a clean EINVAL.
Root cause
sys/dev/video/vga/vga_switcheroo.c:1112-1114:
if (!vgasr_priv->active) {
error = -EINVAL;
goto out;
}
and the final return (error); at line 1221. error was initialized to 0
(line 1078).
This pattern was copied verbatim from the Linux port (the dead-but-compiled
debugfs_write at lines 789β912 uses cnt = -EINVAL and returns cnt) where
the convention is to return a negative errno and have the VFS translate it; in
DragonFlyBSD the same code returns the raw negative value through dev_dwrite.
Threat
No direct security impact; the only effect is wrong error reporting to a root-level writer.
The error value also propagates if any downstream code checks if (error < 0)
instead of if (error).
Defense-in-depth / correctness fix only.
Exploit / PoC
Not a security exploit; demonstration only: as root on a system where
vga_switcheroo module is loaded but no two clients + handler are registered
(i.e. vgasr_priv->active is false), run
printf IGD > /dev/vga_switcheroo; echo $? and observe the returned errno is
not EINVAL (22) but something derived from -22 truncation/interpretation.
Reproducible via kldload vga_switcheroo; printf IGD > /dev/vga_switcheroo
before any GPU/handler registers.
Recommended fix
Return positive errno per DragonFlyBSD convention.
--- a/sys/dev/video/vga/vga_switcheroo.c
+++ b/sys/dev/video/vga/vga_switcheroo.c
@@ -1110,7 +1110,7 @@ vga_switcheroo_write(struct dev_write_args *ap)
if (!vgasr_priv->active) {
- error = -EINVAL;
+ error = EINVAL;
goto out;
}
Related findings
- DF-1511/DF-1512 (siblings): NULL-deref + lock leak in same file.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1513 Β· 1 files| File | Type | Description | Size | |
|---|---|---|---|---|
| fix.diff | suggested-fix | vga_switcheroo_write uses negative errno return convention inconsistent with BSD | 290 B | view raw |
Fix verification
fixedfix.diff applied + combined nativekernel build rc=0 (-Werror)
fix.diff applied + combined nativekernel build rc=0 (-Werror)
Confirmed kernel references
β
Detail
Exploit chain
none (Info severity)
Evidence (decisive lines)
Source-confirmed at sys/dev/video/vga/vga_switcheroo.c:1112: uses negative errno return inconsistent with BSD dev_write
Verified recommended fix
Source-confirmed at sys/dev/video/vga/vga_switcheroo.c:1112: uses negative errno return inconsistent with BSD dev_write
Verdict
Source-confirmed at sys/dev/video/vga/vga_switcheroo.c:1112: uses negative errno return inconsistent with BSD dev_write
No comments yet.