From 865c90e3b628e491f806a4e27ac51a44bde832d3 Mon Sep 17 00:00:00 2001 From: jmng34 Date: Mon, 18 Nov 2019 11:42:28 +0530 Subject: [PATCH] : Restructure (CR): Use copy_from_user function Since we use wrqu structure to pass data from qsap, use copy_from_user function to avoid data corruption. Change-Id: Ic5f4f8631246c932432fc2317829534b521ec438 Reviewed-on: https://gerrit.mot.com/1456951 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Prashanth Chakravarthy Submit-Approved: Raja Phani K --- core/hdd/src/wlan_hdd_hostapd_wext.c | 79 ++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/core/hdd/src/wlan_hdd_hostapd_wext.c b/core/hdd/src/wlan_hdd_hostapd_wext.c index 5a799a32ecd2..1fd564cd165d 100644 --- a/core/hdd/src/wlan_hdd_hostapd_wext.c +++ b/core/hdd/src/wlan_hdd_hostapd_wext.c @@ -347,6 +347,7 @@ static __iw_softap_setparam(struct net_device *dev, mac_handle_t mac_handle; //BEGIN MOT a19110 IKDREL3KK-11113 Fix iwpriv panic int *value; + uint8_t *mot_value; //MOT a19110 IKLOCSEN-3014 Use copy from user int sub_cmd; int set_value; int *tmp = (int *) extra; @@ -358,15 +359,24 @@ static __iw_softap_setparam(struct net_device *dev, hdd_enter_dev(dev); //BEGIN MOT a19110 IKDREL3KK-11113 Fix iwpriv panic to 8998 - if (tmp[0] < 0 || tmp[0] > QCASAP_SET_PHYMODE) { - value = (int *)(wrqu->data.pointer); + //BEGIN MOT a19110 IKLOCSEN-3014 use copy_from_user to avoid junk value + if (tmp[0] < 0 || tmp[0] > QCSAP_SET_BTCOEX_LOW_RSSI_THRESHOLD) { + mot_value = (uint8_t *)kmalloc(wrqu->data.length+1, GFP_KERNEL); + if(copy_from_user((uint8_t *) mot_value, (uint8_t *)(wrqu->data.pointer), wrqu->data.length)) { + hdd_err("%s -- copy_from_user --data pointer failed! bailing", + __func__); + kfree(mot_value); + return -EFAULT; + } + sub_cmd = (int )(*(mot_value + 0)); + set_value = (int )(*(mot_value + 1)); + kfree(mot_value); } else { value = (int *)extra; + sub_cmd = value[0]; + set_value = value[1]; } - - sub_cmd = value[0]; - set_value = value[1]; - + //END IKLOCSEN-3014 if (!adapter || !adapter->hdd_ctx) { hdd_err("Either hostpad adapter is null or Hal ctx is null"); return -EINVAL; @@ -1424,7 +1434,7 @@ int __iw_softap_modify_acl(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct hdd_adapter *adapter = (netdev_priv(dev)); - uint8_t *value = (uint8_t *)(wrqu->data.pointer); + uint8_t *value = (uint8_t *) kmalloc(wrqu->data.length+1, GFP_KERNEL); //MOT IKLOCSEN-3014 uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; int list_type, cmd, i; int ret; @@ -1435,8 +1445,18 @@ int __iw_softap_modify_acl(struct net_device *dev, hdd_ctx = WLAN_HDD_GET_CTX(adapter); ret = wlan_hdd_validate_context(hdd_ctx); - if (0 != ret) - return ret; + if (0 != ret) { + kfree(value); //MOT IKLOCSEN-3014 + return ret; + } + //BEGIN MOT a19110 IKLOCSEN-3014 use copy_from_user to avoid junk value + if(copy_from_user((uint8_t *) value, (uint8_t *)(wrqu->data.pointer), wrqu->data.length)) { + hdd_err("%s -- copy_from_user --data pointer failed! bailing", + __func__); + kfree(value); + return -EFAULT; + } + //END IKLOCSEN-3014 ret = hdd_check_private_wext_control(hdd_ctx, info); if (0 != ret) @@ -1449,6 +1469,7 @@ int __iw_softap_modify_acl(struct net_device *dev, i++; cmd = (int)(*(value + i)); + kfree(value);//MOT IKLOCSEN-3014 hdd_debug("Modify ACL mac:" QDF_MAC_ADDR_FMT " type: %d cmd: %d", QDF_MAC_ADDR_REF(peer_mac), list_type, cmd); @@ -1540,17 +1561,23 @@ static __iw_softap_set_max_tx_power(struct net_device *dev, { struct hdd_adapter *adapter = (netdev_priv(dev)); struct hdd_context *hdd_ctx; - int *value = (int *)(wrqu->data.pointer); + uint8_t *mot_value; int set_value; int ret; struct qdf_mac_addr bssid = QDF_MAC_ADDR_BCAST_INIT; struct qdf_mac_addr selfMac = QDF_MAC_ADDR_BCAST_INIT; hdd_enter_dev(dev); - - if (!value) + mot_value = (uint8_t*)kmalloc(wrqu->data.length+1, GFP_KERNEL); + if (NULL == mot_value) return -ENOMEM; - + if(copy_from_user((uint8_t *)mot_value, (uint8_t *)(wrqu->data.pointer), wrqu->data.length)) { + hdd_err("%s -- copy from user -- data pointer failed! bailing", __func__); + kfree(mot_value); + return -EFAULT; + } + set_value = (int)(*(mot_value + 0)); + kfree(mot_value); hdd_ctx = WLAN_HDD_GET_CTX(adapter); ret = wlan_hdd_validate_context(hdd_ctx); if (0 != ret) @@ -1564,8 +1591,7 @@ static __iw_softap_set_max_tx_power(struct net_device *dev, qdf_copy_macaddr(&bssid, &adapter->mac_addr); qdf_copy_macaddr(&selfMac, &adapter->mac_addr); - set_value = value[0]; - if (QDF_STATUS_SUCCESS != + if (QDF_STATUS_SUCCESS != sme_set_max_tx_power(hdd_ctx->mac_handle, bssid, selfMac, set_value)) { hdd_err("Setting maximum tx power failed"); @@ -1820,7 +1846,7 @@ static __iw_softap_disassoc_sta(struct net_device *dev, { struct hdd_adapter *adapter = (netdev_priv(dev)); struct hdd_context *hdd_ctx; - uint8_t *peer_macaddr; + uint8_t *peer_macaddr = (uint8_t *)kmalloc(wrqu->data.length+1, GFP_KERNEL); //MOT IKLOCSEN-3014 int ret; struct csr_del_sta_params del_sta_params; @@ -1828,22 +1854,33 @@ static __iw_softap_disassoc_sta(struct net_device *dev, if (!capable(CAP_NET_ADMIN)) { hdd_err("permission check failed"); + kfree(peer_macaddr); //MOT IKLOCSEN-3014 return -EPERM; } hdd_ctx = WLAN_HDD_GET_CTX(adapter); ret = wlan_hdd_validate_context(hdd_ctx); - if (0 != ret) + if (0 != ret){ + kfree(peer_macaddr); //MOT IKLOCSEN-3014 return ret; - + } ret = hdd_check_private_wext_control(hdd_ctx, info); - if (0 != ret) + if (0 != ret){ + kfree(peer_macaddr); //MOT IKLOCSEN-3014 return ret; + } /* iwpriv tool or framework calls this ioctl with * data passed in extra (less than 16 octets); */ - peer_macaddr = (uint8_t *) (wrqu->data.pointer); + //BEGIN MOT a19110 IKLOCSEN-3014 use copy_from_user to avoid junk value + if(copy_from_user((uint8_t *) peer_macaddr, (uint8_t *)(wrqu->data.pointer), wrqu->data.length)) { + hdd_err("%s -- copy_from_user --data pointer failed! bailing", + __func__); + kfree(peer_macaddr); + return -EFAULT; + } + //END IKLOCSEN-3014 hdd_debug("data " QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(peer_macaddr)); @@ -1852,7 +1889,7 @@ static __iw_softap_disassoc_sta(struct net_device *dev, SIR_MAC_MGMT_DISASSOC, &del_sta_params); hdd_softap_sta_disassoc(adapter, &del_sta_params); - + kfree(peer_macaddr); //MOT IKLOCSEN-3014 hdd_exit(); return 0; }