Message ID | 1465223659-11530-1-git-send-email-prasunmaiti87@gmail.com (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Johannes Berg |
Headers | show |
On Mon, 2016-06-06 at 20:04 +0530, Prasun Maiti wrote: > iwpriv app uses iw_point structure to send data to Kernel. The > iw_point > structure holds a pointer. For compatibility Kernel converts the > pointer > as required for WEXT IOCTLs (SIOCIWFIRST to SIOCIWLAST). Some drivers > may use iw_handler_def.private_args to populate iwpriv commands > instead > of iw_handler_def.private. For those case, the IOCTLs from > SIOCIWFIRSTPRIV to SIOCIWLASTPRIV will follow the path > ndo_do_ioctl(). > Accordingly when the filled up iw_point structure comes from 32 bit > iwpriv to 64 bit Kernel, Kernel will not convert the pointer and > sends > it to driver. So, the driver may get the invalid data. > Applied. johannes -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index 6250b1c..a96dcc6 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c @@ -958,8 +958,28 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, 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); + if (dev->netdev_ops->ndo_do_ioctl) { +#ifdef CONFIG_COMPAT + if (info->flags & IW_REQUEST_FLAG_COMPAT) { + int ret = 0; + struct iwreq iwr_lcl; + struct compat_iw_point *iwp_compat = (void *) &iwr->u.data; + + memcpy(&iwr_lcl, iwr, sizeof(struct iwreq)); + iwr_lcl.u.data.pointer = compat_ptr(iwp_compat->pointer); + iwr_lcl.u.data.length = iwp_compat->length; + iwr_lcl.u.data.flags = iwp_compat->flags; + + ret = dev->netdev_ops->ndo_do_ioctl(dev, (void *) &iwr_lcl, cmd); + + iwp_compat->pointer = ptr_to_compat(iwr_lcl.u.data.pointer); + iwp_compat->length = iwr_lcl.u.data.length; + iwp_compat->flags = iwr_lcl.u.data.flags; + return ret; + } else +#endif + return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd); + } return -EOPNOTSUPP; }