β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-1513

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.

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;
    }
  • DF-1511/DF-1512 (siblings): NULL-deref + lock leak in same file.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1513 Β· 1 files
FileTypeDescriptionSize
fix.diff suggested-fix vga_switcheroo_write uses negative errno return convention inconsistent with BSD 290 B view raw

Fix verification

fixed
baseline reproduced→ patch + rebuild →patched clean

fix.diff applied + combined nativekernel build rc=0 (-Werror)

fix.diff applied + combined nativekernel build rc=0 (-Werror)
↓ fix.diffcombined build rc=0

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