Commit 4b153ca9 authored by David S. Miller's avatar David S. Miller

Merge tag 'mac80211-for-davem-2017-06-16' of...

Merge tag 'mac80211-for-davem-2017-06-16' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211

Johannes Berg says:

====================
Here's just the fix for that ancient bug:
 * remove wext calling ndo_do_ioctl, since nobody needs
   that now and it makes the type change easier
 * use struct iwreq instead of struct ifreq almost everywhere
   in wireless extensions code
 * copy only struct iwreq from userspace in dev_ioctl for the
   wireless extensions, since it's smaller than struct ifreq
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 46f8cd9d 68dd02d1
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
struct net; struct net;
#ifdef CONFIG_WEXT_CORE #ifdef CONFIG_WEXT_CORE
int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd, int wext_handle_ioctl(struct net *net, struct iwreq *iwr, unsigned int cmd,
void __user *arg); void __user *arg);
int compat_wext_handle_ioctl(struct net *net, unsigned int cmd, int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
unsigned long arg); unsigned long arg);
...@@ -14,7 +14,7 @@ int compat_wext_handle_ioctl(struct net *net, unsigned int cmd, ...@@ -14,7 +14,7 @@ int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
struct iw_statistics *get_wireless_stats(struct net_device *dev); struct iw_statistics *get_wireless_stats(struct net_device *dev);
int call_commit_handler(struct net_device *dev); int call_commit_handler(struct net_device *dev);
#else #else
static inline int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd, static inline int wext_handle_ioctl(struct net *net, struct iwreq *iwr, unsigned int cmd,
void __user *arg) void __user *arg)
{ {
return -EINVAL; return -EINVAL;
......
...@@ -410,6 +410,22 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg) ...@@ -410,6 +410,22 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
if (cmd == SIOCGIFNAME) if (cmd == SIOCGIFNAME)
return dev_ifname(net, (struct ifreq __user *)arg); 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))) if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
return -EFAULT; return -EFAULT;
...@@ -559,9 +575,6 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg) ...@@ -559,9 +575,6 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
ret = -EFAULT; ret = -EFAULT;
return ret; return ret;
} }
/* Take care of Wireless Extensions */
if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
return wext_handle_ioctl(net, &ifr, cmd, arg);
return -ENOTTY; return -ENOTTY;
} }
} }
...@@ -914,13 +914,12 @@ int call_commit_handler(struct net_device *dev) ...@@ -914,13 +914,12 @@ int call_commit_handler(struct net_device *dev)
* Main IOCTl dispatcher. * Main IOCTl dispatcher.
* Check the type of IOCTL and call the appropriate wrapper... * Check the type of IOCTL and call the appropriate wrapper...
*/ */
static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, static int wireless_process_ioctl(struct net *net, struct iwreq *iwr,
unsigned int cmd, unsigned int cmd,
struct iw_request_info *info, struct iw_request_info *info,
wext_ioctl_func standard, wext_ioctl_func standard,
wext_ioctl_func private) wext_ioctl_func private)
{ {
struct iwreq *iwr = (struct iwreq *) ifr;
struct net_device *dev; struct net_device *dev;
iw_handler handler; iw_handler handler;
...@@ -928,7 +927,7 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, ...@@ -928,7 +927,7 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr,
* The copy_to/from_user() of ifr is also dealt with in there */ * The copy_to/from_user() of ifr is also dealt with in there */
/* Make sure the device exist */ /* Make sure the device exist */
if ((dev = __dev_get_by_name(net, ifr->ifr_name)) == NULL) if ((dev = __dev_get_by_name(net, iwr->ifr_name)) == NULL)
return -ENODEV; return -ENODEV;
/* A bunch of special cases, then the generic case... /* A bunch of special cases, then the generic case...
...@@ -957,9 +956,6 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, ...@@ -957,9 +956,6 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr,
else if (private) else if (private)
return private(dev, iwr, cmd, info, handler); return private(dev, iwr, cmd, info, handler);
} }
/* Old driver API : call driver ioctl handler */
if (dev->netdev_ops->ndo_do_ioctl)
return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -977,7 +973,7 @@ static int wext_permission_check(unsigned int cmd) ...@@ -977,7 +973,7 @@ static int wext_permission_check(unsigned int cmd)
} }
/* entry point from dev ioctl */ /* entry point from dev ioctl */
static int wext_ioctl_dispatch(struct net *net, struct ifreq *ifr, static int wext_ioctl_dispatch(struct net *net, struct iwreq *iwr,
unsigned int cmd, struct iw_request_info *info, unsigned int cmd, struct iw_request_info *info,
wext_ioctl_func standard, wext_ioctl_func standard,
wext_ioctl_func private) wext_ioctl_func private)
...@@ -987,9 +983,9 @@ static int wext_ioctl_dispatch(struct net *net, struct ifreq *ifr, ...@@ -987,9 +983,9 @@ static int wext_ioctl_dispatch(struct net *net, struct ifreq *ifr,
if (ret) if (ret)
return ret; return ret;
dev_load(net, ifr->ifr_name); dev_load(net, iwr->ifr_name);
rtnl_lock(); rtnl_lock();
ret = wireless_process_ioctl(net, ifr, cmd, info, standard, private); ret = wireless_process_ioctl(net, iwr, cmd, info, standard, private);
rtnl_unlock(); rtnl_unlock();
return ret; return ret;
...@@ -1039,18 +1035,18 @@ static int ioctl_standard_call(struct net_device * dev, ...@@ -1039,18 +1035,18 @@ static int ioctl_standard_call(struct net_device * dev,
} }
int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd, int wext_handle_ioctl(struct net *net, struct iwreq *iwr, unsigned int cmd,
void __user *arg) void __user *arg)
{ {
struct iw_request_info info = { .cmd = cmd, .flags = 0 }; struct iw_request_info info = { .cmd = cmd, .flags = 0 };
int ret; int ret;
ret = wext_ioctl_dispatch(net, ifr, cmd, &info, ret = wext_ioctl_dispatch(net, iwr, cmd, &info,
ioctl_standard_call, ioctl_standard_call,
ioctl_private_call); ioctl_private_call);
if (ret >= 0 && if (ret >= 0 &&
IW_IS_GET(cmd) && IW_IS_GET(cmd) &&
copy_to_user(arg, ifr, sizeof(struct iwreq))) copy_to_user(arg, iwr, sizeof(struct iwreq)))
return -EFAULT; return -EFAULT;
return ret; return ret;
...@@ -1107,7 +1103,7 @@ int compat_wext_handle_ioctl(struct net *net, unsigned int cmd, ...@@ -1107,7 +1103,7 @@ int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
info.cmd = cmd; info.cmd = cmd;
info.flags = IW_REQUEST_FLAG_COMPAT; info.flags = IW_REQUEST_FLAG_COMPAT;
ret = wext_ioctl_dispatch(net, (struct ifreq *) &iwr, cmd, &info, ret = wext_ioctl_dispatch(net, &iwr, cmd, &info,
compat_standard_call, compat_standard_call,
compat_private_call); compat_private_call);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment