staging: rtlwifi: use siocdevprivate
authorArnd Bergmann <arnd@arndb.de>
Tue, 27 Jul 2021 13:44:48 +0000 (15:44 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 27 Jul 2021 19:11:43 +0000 (20:11 +0100)
rtl8188eu has an "android private" ioctl command multiplexer
that is not currently safe for use in compat mode because
of its triple-indirect pointer.

rtl8723bs uses a different interface on the SIOCDEVPRIVATE
command, based on the iwpriv data structure

Both also have normal unreachable iwpriv commands, and all
of the above should probably just get removed. For the
moment, just switch over to the new interface.

Cc: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/staging/rtl8188eu/include/osdep_intf.h
drivers/staging/rtl8188eu/include/rtw_android.h
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
drivers/staging/rtl8188eu/os_dep/os_intfs.c
drivers/staging/rtl8188eu/os_dep/rtw_android.c
drivers/staging/rtl8723bs/include/osdep_intf.h
drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
drivers/staging/rtl8723bs/os_dep/os_intfs.c

index 5012b9176526bbe116a2bb36ad4d4b687fb5f6d1..34decb03e92f2282155f91a5002392647613198a 100644 (file)
@@ -22,6 +22,8 @@ void rtw_stop_drv_threads(struct adapter *padapter);
 void rtw_cancel_all_timer(struct adapter *padapter);
 
 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+int rtw_android_priv_cmd(struct net_device *dev, struct ifreq *rq,
+                        void __user *data, int cmd);
 
 struct net_device *rtw_init_netdev(void);
 u16 rtw_recv_select_queue(struct sk_buff *skb);
index 2c26993b8205e0177af5558f477c10086a54acc1..3018fc1e8de825f3c5ef63d2f9da6f03ce68ac85 100644 (file)
@@ -45,6 +45,7 @@ enum ANDROID_WIFI_CMD {
        ANDROID_WIFI_CMD_MAX
 };
 
-int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd);
+int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr,
+                        void __user *data, int cmd);
 
 #endif /* __RTW_ANDROID_H__ */
index b958a8d882b09b421de20844c5b93dac7a9270ec..193a3dde462cfd46bb11f036eed9951ecf78f129 100644 (file)
@@ -2769,9 +2769,6 @@ int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
                break;
 #endif /*  CONFIG_88EU_AP_MODE */
-       case (SIOCDEVPRIVATE + 1):
-               ret = rtw_android_priv_cmd(dev, rq, cmd);
-               break;
        default:
                ret = -EOPNOTSUPP;
                break;
index 423c382e3d20e80bc2a0fc76b05e06147aaf0d98..596e03e7b2860dc3b6ea54950737b1a345f58b0a 100644 (file)
@@ -288,6 +288,7 @@ static const struct net_device_ops rtw_netdev_ops = {
        .ndo_set_mac_address = rtw_net_set_mac_address,
        .ndo_get_stats = rtw_net_get_stats,
        .ndo_do_ioctl = rtw_ioctl,
+       .ndo_siocdevprivate = rtw_android_priv_cmd,
 };
 
 static const struct device_type wlan_type = {
index 3c5446999686729a9d95524448f024d35e643bb6..a13df38803789a770a9f9629a4518079930b4d55 100644 (file)
@@ -5,6 +5,7 @@
  *
  ******************************************************************************/
 
+#include <linux/compat.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 
@@ -116,7 +117,8 @@ static int android_get_p2p_addr(struct net_device *net, char *command,
        return ETH_ALEN;
 }
 
-int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
+int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr,
+                        void __user *data, int cmd)
 {
        int ret = 0;
        char *command;
@@ -124,9 +126,15 @@ int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
        int bytes_written = 0;
        struct android_wifi_priv_cmd priv_cmd;
 
-       if (!ifr->ifr_data)
+       if (cmd != SIOCDEVPRIVATE)
+               return -EOPNOTSUPP;
+
+       if (in_compat_syscall()) /* to be implemented */
+               return -EOPNOTSUPP;
+
+       if (!data)
                return -EINVAL;
-       if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(priv_cmd)))
+       if (copy_from_user(&priv_cmd, data, sizeof(priv_cmd)))
                return -EFAULT;
        if (priv_cmd.total_len < 1)
                return -EINVAL;
index 111e0179712ac6e0b8846c65e30f5dd3716618d0..5badd441c14b6900aa674d53006ed4cd3307fbea 100644 (file)
@@ -48,6 +48,8 @@ void rtw_stop_drv_threads(struct adapter *padapter);
 void rtw_cancel_all_timer(struct adapter *padapter);
 
 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+int rtw_siocdevprivate(struct net_device *dev, struct ifreq *rq,
+                      void __user *data, int cmd);
 
 int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname);
 struct net_device *rtw_init_netdev(struct adapter *padapter);
index f95000df8942291178f9d2b39b8d1165ada517d8..aa7bd76bb5f1c4f6ff21e489076019a5d6a1862a 100644 (file)
@@ -4485,6 +4485,21 @@ exit:
        return err;
 }
 
+int rtw_siocdevprivate(struct net_device *dev, struct ifreq *rq,
+                      void __user *data, int cmd)
+{
+       struct iwreq *wrq = (struct iwreq *)rq;
+
+       /* little hope of fixing this, better remove the whole function */
+       if (in_compat_syscall())
+               return -EOPNOTSUPP;
+
+       if (cmd != SIOCDEVPRIVATE)
+               return -EOPNOTSUPP;
+
+       return rtw_ioctl_wext_private(dev, &wrq->u);
+}
+
 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct iwreq *wrq = (struct iwreq *)rq;
@@ -4497,9 +4512,6 @@ int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        case RTL_IOCTL_HOSTAPD:
                ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
                break;
-       case SIOCDEVPRIVATE:
-               ret = rtw_ioctl_wext_private(dev, &wrq->u);
-               break;
        default:
                ret = -EOPNOTSUPP;
                break;
index 648456b992bbcf8f6efbc2c1f064abfad2dec8f0..9e38b53d3b4a58f00052d0220256d60568238dc9 100644 (file)
@@ -459,6 +459,7 @@ static const struct net_device_ops rtw_netdev_ops = {
        .ndo_set_mac_address = rtw_net_set_mac_address,
        .ndo_get_stats = rtw_net_get_stats,
        .ndo_do_ioctl = rtw_ioctl,
+       .ndo_siocdevprivate = rtw_siocdevprivate,
 };
 
 int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname)