diff options
Diffstat (limited to 'net/core/dev_ioctl.c')
| -rw-r--r-- | net/core/dev_ioctl.c | 19 | 
1 files changed, 16 insertions, 3 deletions
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c index b94b1d293506..27fad31784a8 100644 --- a/net/core/dev_ioctl.c +++ b/net/core/dev_ioctl.c @@ -410,6 +410,22 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)  	if (cmd == SIOCGIFNAME)  		return dev_ifname(net, (struct ifreq __user *)arg); +	/* +	 * Take care of Wireless Extensions. Unfortunately struct iwreq +	 * isn't a proper subset of struct ifreq (it's 8 byte shorter) +	 * so we need to treat it specially, otherwise applications may +	 * fault if the struct they're passing happens to land at the +	 * end of a mapped page. +	 */ +	if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { +		struct iwreq iwr; + +		if (copy_from_user(&iwr, arg, sizeof(iwr))) +			return -EFAULT; + +		return wext_handle_ioctl(net, &iwr, cmd, arg); +	} +  	if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))  		return -EFAULT; @@ -559,9 +575,6 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)  				ret = -EFAULT;  			return ret;  		} -		/* Take care of Wireless Extensions */ -		if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) -			return wext_handle_ioctl(net, &ifr, cmd, arg);  		return -ENOTTY;  	}  }  |