Safeguard
Application Security•

CWE-782 Exposed IOCTL with Insufficient Access Control

A driver IOCTL that anyone can call becomes a privileged API for attackers. See how CWE-782 appears in Windows and Unix drivers and how to restrict access.

Safeguard Security Team
3 min read

CWE-782 describes a driver that exposes an IOCTL with privileged functionality and does not enforce access control on it. Any local caller who can reach the device can invoke it.

This affects driver authors on Unix and Windows, and security teams that must decide whether a vendor driver is safe to deploy.

How it happens

An IOCTL is a control call from user space into a driver. Developers often assume that only their own trusted service will ever call it. So they skip the permission check, and they skip input validation too, because the caller is "trusted."

MITRE points out the second effect: even if the exposed function is benign, the lack of validation means flaws that would never be reachable by an attacker become reachable once the attacker can call the IOCTL directly.

The details differ between operating systems and versions, so the exact method of attack and the right defense vary.

Examples from the record:

  • CVE-2009-2208: an operating system did not enforce permissions on an IOCTL that could change network settings.
  • CVE-2008-3831: a device driver did not restrict ioctl calls to its direct rendering manager.
  • CVE-2008-3525: an ioctl did not check for a required capability before processing certain requests.

A schematic Linux handler with the problem:

static long dev_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
    switch (cmd) {
    case DEV_SET_NET_CONFIG:
        return apply_config((void __user *)arg);   /* no capability check */
    }
    return -ENOTTY;
}

What an attacker gains

Attackers can invoke any functionality the IOCTL offers. The MITRE record says the consequence depends on that functionality, and lists integrity, availability and confidentiality as possible impacts. Changing network settings, reaching hardware, or escalating to kernel privilege are all plausible depending on the driver.

How to find it

  • Enumerate every IOCTL a driver handles and write down what each one can do.
  • Check the device object permissions. On Windows, see who can open the device. On Unix, look at the device node mode and owner.
  • Review each handler for an explicit privilege check before work begins.
  • Try calling each control code from an unprivileged account in a test environment.
  • Fuzz the interface, because unvalidated inputs behind an exposed IOCTL tend to crash.

How to fix it

  1. Restrict the device itself, so only the accounts that need it can open it.
  2. Check privilege inside each handler that does anything sensitive, using the operating system's capability or access check.
    case DEV_SET_NET_CONFIG:
        if (!capable(CAP_NET_ADMIN))
            return -EPERM;
        return apply_config((void __user *)arg);
  1. Validate every input as if the caller were hostile, since the access control may have a gap.
  2. Expose fewer control codes. Remove debug and test IOCTLs from shipped builds.

For the pointer side of the problem, see CWE-781.

Quick check

If the IOCTL only does something harmless, is access control still needed?

Yes. Weak input handling behind it becomes reachable by anyone who can call it.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.