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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEExu3sM/nZ1eRSfR9Ha3t4Rpy0AB0FAllDhUsACgkQa3t4Rpy0 AB2ttw//SepU66meFuzYy+bFbR38Q2sguKADmSN9jjng3oPyKhHKfEJwRusZZ3zg eEIk/NNB2iPTMLSaa4kR1Wclcae0jq5KgO8HwJBLvS7peCXWKx03vnP4Dy7yJ/6U VvOk+3JoudnQFhdDnIg+RVsGbwLx0hlq2l727U1Sp6kFyChK2etLikPzVKkEgVnG 2R/l1BhDqXdQ6Lh7nXWa6O9pwaqkpnPOuJvipJzmUQRB/4GBNjBxSK6J+ac98sm6 +KCCONBvBBMBago0xySTVURzMTrhW2UH1cE6ITQYjlShB/zsyilYkECvFzOSAYZL u9ob1yCAmZwDqhtvEUSi7CEfLtcO43I0XDF4oL00xfmYD9alm9dJPAlvZ1ihsrw7 ojBDjyykUstWRSeP8zETTdYDIMSPVsed1Y6NzQiy+el/6U3//+o2FcOShqUh89lx OIlQwX5i9LBRC/POQ6L8R4VPelNZ/czKMNlq1Z+ubNM9i3PT/8gGf6WapbMPpNUk AqAsB13tR17QmLjNpdVxHtoNvD9aceYaFkN+GXRNSb3pJNoJouedx6d5maFYJAju GRdZXBV14Z7bamKB3x9EAjpD3DHplJw4m8BvwnBr9zWkGyAvoNsHIC5h8ynzjWSp J7KpXPB9IKX6ne+1gCNrrPod2AmK4sWIaAT/SaWMCoHjV4m74k4= =O240 -----END PGP SIGNATURE----- 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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
4b153ca989
|
@ -6,7 +6,7 @@
|
|||
struct net;
|
||||
|
||||
#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);
|
||||
int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
|
@ -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);
|
||||
int call_commit_handler(struct net_device *dev);
|
||||
#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)
|
||||
{
|
||||
return -EINVAL;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -914,13 +914,12 @@ int call_commit_handler(struct net_device *dev)
|
|||
* Main IOCTl dispatcher.
|
||||
* 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,
|
||||
struct iw_request_info *info,
|
||||
wext_ioctl_func standard,
|
||||
wext_ioctl_func private)
|
||||
{
|
||||
struct iwreq *iwr = (struct iwreq *) ifr;
|
||||
struct net_device *dev;
|
||||
iw_handler handler;
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
/* 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;
|
||||
|
||||
/* A bunch of special cases, then the generic case...
|
||||
|
@ -957,9 +956,6 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr,
|
|||
else if (private)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -977,7 +973,7 @@ static int wext_permission_check(unsigned int cmd)
|
|||
}
|
||||
|
||||
/* 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,
|
||||
wext_ioctl_func standard,
|
||||
wext_ioctl_func private)
|
||||
|
@ -987,9 +983,9 @@ static int wext_ioctl_dispatch(struct net *net, struct ifreq *ifr,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_load(net, ifr->ifr_name);
|
||||
dev_load(net, iwr->ifr_name);
|
||||
rtnl_lock();
|
||||
ret = wireless_process_ioctl(net, ifr, cmd, info, standard, private);
|
||||
ret = wireless_process_ioctl(net, iwr, cmd, info, standard, private);
|
||||
rtnl_unlock();
|
||||
|
||||
return ret;
|
||||
|
@ -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)
|
||||
{
|
||||
struct iw_request_info info = { .cmd = cmd, .flags = 0 };
|
||||
int ret;
|
||||
|
||||
ret = wext_ioctl_dispatch(net, ifr, cmd, &info,
|
||||
ret = wext_ioctl_dispatch(net, iwr, cmd, &info,
|
||||
ioctl_standard_call,
|
||||
ioctl_private_call);
|
||||
if (ret >= 0 &&
|
||||
IW_IS_GET(cmd) &&
|
||||
copy_to_user(arg, ifr, sizeof(struct iwreq)))
|
||||
copy_to_user(arg, iwr, sizeof(struct iwreq)))
|
||||
return -EFAULT;
|
||||
|
||||
return ret;
|
||||
|
@ -1107,7 +1103,7 @@ int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
|
|||
info.cmd = cmd;
|
||||
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_private_call);
|
||||
|
||||
|
|
Loading…
Reference in New Issue