staging: vt6655: fix direct dereferencing of user pointer
authorGuillaume Clement <gclement@baobob.org>
Fri, 25 Jul 2014 12:47:23 +0000 (14:47 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 30 Jul 2014 23:36:27 +0000 (16:36 -0700)
Sparse reported that the data from tagSCmdRequest is given by
userspace, so it should be tagged as such.

Later, we were memcomparing and dereferencing it without first copying
it, fix that as well.

Signed-off-by: Guillaume Clement <gclement@baobob.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/vt6655/iocmd.h
drivers/staging/vt6655/iwctl.c
drivers/staging/vt6655/iwctl.h

index ae037ec5b36656820588e114a1c2d927f2e9343f..a665cfd8a48225c9bb41b50e57b5323219414a14 100644 (file)
@@ -94,7 +94,7 @@ typedef enum tagWZONETYPE {
 #pragma pack(1)
 typedef struct tagSCmdRequest {
        u8          name[16];
-       void    *data;
+       void __user *data;
        u16         wResult;
        u16     wCmdCode;
 } SCmdRequest, *PSCmdRequest;
index 501cd64774395e9d3fafc44c5ce16493acea4b30..7ce23b57e78da3b80764a8c943c0342ec8935aae 100644 (file)
@@ -1621,17 +1621,24 @@ int iwctl_giwauth(struct net_device *dev,
 int iwctl_siwgenie(struct net_device *dev,
                   struct iw_request_info *info,
                   struct iw_point *wrq,
-                  char *extra)
+                  char __user *extra)
 {
        PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
        PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
        int ret = 0;
+       char length;
 
        if (wrq->length) {
-               if ((wrq->length < 2) || (extra[1]+2 != wrq->length)) {
-                       ret = -EINVAL;
-                       goto out;
-               }
+               if (wrq->length < 2)
+                       return -EINVAL;
+
+               ret = get_user(length, extra + 1);
+               if (ret)
+                       return ret;
+
+               if (length + 2 != wrq->length)
+                       return -EINVAL;
+
                if (wrq->length > MAX_WPA_IE_LEN) {
                        ret = -ENOMEM;
                        goto out;
@@ -1654,7 +1661,7 @@ out://not completely ...not necessary in wpa_supplicant 0.5.8
 int iwctl_giwgenie(struct net_device *dev,
                   struct iw_request_info *info,
                   struct iw_point *wrq,
-                  char *extra)
+                  char __user *extra)
 {
        PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
        PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
@@ -1801,18 +1808,23 @@ int iwctl_giwencodeext(struct net_device *dev,
 int iwctl_siwmlme(struct net_device *dev,
                  struct iw_request_info *info,
                  struct iw_point *wrq,
-                 char *extra)
+                 char __user *extra)
 {
        PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
        PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
-       struct iw_mlme *mlme = (struct iw_mlme *)extra;
+       struct iw_mlme mime;
+
        int ret = 0;
 
-       if (memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)) {
+       ret = copy_from_user(&mime, extra, sizeof(mime));
+       if (ret)
+               return -EFAULT;
+
+       if (memcmp(pMgmt->abyCurrBSSID, mime.addr.sa_data, ETH_ALEN)) {
                ret = -EINVAL;
                return ret;
        }
-       switch (mlme->cmd) {
+       switch (mime.cmd) {
        case IW_MLME_DEAUTH:
                //this command seems to be not complete,please test it --einsnliu
                //bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (unsigned char *)&reason);
index de0a337b543a468672989efa51af7ae8abaf970e..7dd63102182dc3336c9d04ec5d6e50818f8412d7 100644 (file)
@@ -176,12 +176,12 @@ int iwctl_giwauth(struct net_device *dev,
 int iwctl_siwgenie(struct net_device *dev,
                   struct iw_request_info *info,
                   struct iw_point *wrq,
-                  char *extra);
+                  char __user *extra);
 
 int iwctl_giwgenie(struct net_device *dev,
                   struct iw_request_info *info,
                   struct iw_point *wrq,
-                  char *extra);
+                  char __user *extra);
 
 int iwctl_siwencodeext(struct net_device *dev,
                       struct iw_request_info *info,
@@ -196,7 +196,7 @@ int iwctl_giwencodeext(struct net_device *dev,
 int iwctl_siwmlme(struct net_device *dev,
                  struct iw_request_info *info,
                  struct iw_point *wrq,
-                 char *extra);
+                 char __user *extra);
 #endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
 //End Add -- //2008-0409-07, <Add> by Einsn Liu