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
- Restrict the device itself, so only the accounts that need it can open it.
- 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);
- Validate every input as if the caller were hostile, since the access control may have a gap.
- 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.