diff options
| author | yang-cy.chen <yang-cy.chen@mediatek.com> | 2016-03-16 03:03:06 +0800 |
|---|---|---|
| committer | Moyster <oysterized@gmail.com> | 2016-08-26 16:02:17 +0200 |
| commit | f5bb9a717fb164d134064c24a88038e126e36ea2 (patch) | |
| tree | 9f871e1bdd4398cf26b1d0a6a282603e20cc3673 /drivers | |
| parent | ed4fff76be6333a98a6736bc2550fffb7d5e8053 (diff) | |
Security vulnerability in Mediatek WIFI driver
Problem:
No boundary protection of the copy length when call copy_from_user()
Solution:
add boundary check to prevent buffer overflow
Bug num:27549705
Change-Id: I31fc82c3328d017ca9d7c6232a9699538ff3a398
Signed-off-by: yang-cy.chen <yang-cy.chen@mediatek.com>
Diffstat (limited to 'drivers')
7 files changed, 167 insertions, 99 deletions
diff --git a/drivers/misc/mediatek/connectivity/conn_soc/common/linux/pub/wmt_chrdev_wifi.c b/drivers/misc/mediatek/connectivity/conn_soc/common/linux/pub/wmt_chrdev_wifi.c index 0ceff53b2..cfea89c10 100644 --- a/drivers/misc/mediatek/connectivity/conn_soc/common/linux/pub/wmt_chrdev_wifi.c +++ b/drivers/misc/mediatek/connectivity/conn_soc/common/linux/pub/wmt_chrdev_wifi.c @@ -332,6 +332,7 @@ ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff struct net_device *netdev = NULL; PARAM_CUSTOM_P2P_SET_STRUC_T p2pmode; INT32 wait_cnt = 0; + int copy_size = 0; down(&wr_mtx); if (count <= 0) { @@ -339,8 +340,9 @@ ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff goto done; } - if (0 == copy_from_user(local, buf, (count > sizeof(local)) ? sizeof(local) : count)) { - local[11] = 0; + copy_size = min(sizeof(local) - 1, count); + if (0 == copy_from_user(local, buf, copy_size)) { + WIFI_INFO_FUNC("WIFI_write %s\n", local); if (local[0] == '0') { diff --git a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/include/wlan_lib.h b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/include/wlan_lib.h index c9d4ec39a..10bcd64a4 100644 --- a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/include/wlan_lib.h +++ b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/include/wlan_lib.h @@ -323,7 +323,7 @@ */ #define MAX_NUM_GROUP_ADDR 32 /* max number of group addresses */ - +#define OID_SET_GET_STRUCT_LENGTH 4096 /* For SET_STRUCT/GET_STRUCT */ #define TX_CS_TCP_UDP_GEN BIT(1) diff --git a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_p2p.c b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_p2p.c index e779bd711..2797ece81 100644 --- a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_p2p.c +++ b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_p2p.c @@ -2246,6 +2246,10 @@ p2pDoIOCTL( /* Set Encryption Material after 4-way handshaking is done */ if (prIwReq->u.encoding.pointer) { u4ExtraSize = prIwReq->u.encoding.length; + if (u4ExtraSize > sizeof(struct iw_encode_ext)) { + ret = -EINVAL; + break; + } prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); if (!prExtraBuf) { @@ -2253,13 +2257,11 @@ p2pDoIOCTL( break; } - if (copy_from_user(prExtraBuf, - prIwReq->u.encoding.pointer, - prIwReq->u.encoding.length)) { + if (copy_from_user(prExtraBuf, prIwReq->u.encoding.pointer, u4ExtraSize)) { ret = -EFAULT; } } - else if (prIwReq->u.encoding.length != 0) { + else { ret = -EINVAL; break; } @@ -3047,6 +3049,10 @@ mtk_p2p_wext_set_key( do { if (wrqu->encoding.pointer) { u4ExtraSize = wrqu->encoding.length; + if (u4ExtraSize > sizeof(struct iw_encode_ext)) { + ret = -EINVAL; + break; + } prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); if (!prExtraBuf) { @@ -3054,14 +3060,12 @@ mtk_p2p_wext_set_key( break; } - if (copy_from_user(prExtraBuf, - wrqu->encoding.pointer, - wrqu->encoding.length)) { + if (copy_from_user(prExtraBuf, wrqu->encoding.pointer, u4ExtraSize)) { ret = -EFAULT; break; } } - else if (wrqu->encoding.length != 0) { + else { ret = -EINVAL; break; } @@ -3800,6 +3804,7 @@ mtk_p2p_wext_password_ready( P_GLUE_INFO_T prGlueInfo = NULL; P_IW_P2P_PASSWORD_READY prPasswordReady = (P_IW_P2P_PASSWORD_READY)extra; P_P2P_CONNECTION_SETTINGS_T prConnSettings; + UINT_16 u2CmdLen = 0; ASSERT(prDev); @@ -3810,11 +3815,12 @@ mtk_p2p_wext_password_ready( ASSERT(prAdapter); prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; + u2CmdLen = prPasswordReady->probe_req_len; /* retrieve IE for Probe Request */ - if (prPasswordReady->probe_req_len > 0) { - if (prPasswordReady->probe_req_len <= MAX_WSC_IE_LENGTH) { - if (copy_from_user(prGlueInfo->prP2PInfo->aucWSCIE[1], prPasswordReady->probe_req_ie, prPasswordReady->probe_req_len)) { + if (u2CmdLen > 0) { + if (u2CmdLen <= MAX_WSC_IE_LENGTH) { + if (copy_from_user(prGlueInfo->prP2PInfo->aucWSCIE[1], prPasswordReady->probe_req_ie, u2CmdLen)) { return -EFAULT; } } @@ -3823,12 +3829,13 @@ mtk_p2p_wext_password_ready( } } - prGlueInfo->prP2PInfo->u2WSCIELen[1] = prPasswordReady->probe_req_len; + prGlueInfo->prP2PInfo->u2WSCIELen[1] = u2CmdLen; /* retrieve IE for Probe Response */ - if (prPasswordReady->probe_rsp_len > 0) { - if (prPasswordReady->probe_rsp_len <= MAX_WSC_IE_LENGTH) { - if (copy_from_user(prGlueInfo->prP2PInfo->aucWSCIE[2], prPasswordReady->probe_rsp_ie, prPasswordReady->probe_rsp_len)) { + u2CmdLen = prPasswordReady->probe_rsp_len; + if (u2CmdLen > 0) { + if (u2CmdLen <= MAX_WSC_IE_LENGTH) { + if (copy_from_user(prGlueInfo->prP2PInfo->aucWSCIE[2], prPasswordReady->probe_rsp_ie, u2CmdLen)) { return -EFAULT; } } @@ -3837,7 +3844,7 @@ mtk_p2p_wext_password_ready( } } - prGlueInfo->prP2PInfo->u2WSCIELen[2] = prPasswordReady->probe_rsp_len; + prGlueInfo->prP2PInfo->u2WSCIELen[2] = u2CmdLen; switch (prPasswordReady->active_config_method) { case 1: @@ -4379,6 +4386,7 @@ mtk_p2p_wext_set_struct ( { int status = 0; UINT_32 u4SubCmd = 0; + UINT_32 u4CmdLen = 0; P_GLUE_INFO_T prGlueInfo = NULL; P_IW_P2P_TRANSPORT_STRUCT prP2PReq = NULL; @@ -4393,20 +4401,27 @@ mtk_p2p_wext_set_struct ( ASSERT(prGlueInfo); u4SubCmd = (UINT_32) wrqu->data.flags; + u4CmdLen = wrqu->data.length; kalMemZero(&prGlueInfo->prP2PInfo->aucOidBuf[0], sizeof(prGlueInfo->prP2PInfo->aucOidBuf)); switch (u4SubCmd) { case PRIV_CMD_OID: + if (u4CmdLen > OID_SET_GET_STRUCT_LENGTH) { + printk(KERN_INFO DRV_NAME"input data length invalid %ld\n", u4CmdLen); + status = -EINVAL; + break; + } + if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, - wrqu->data.length)) { + u4CmdLen)) { status = -EFAULT; break; } - if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length)) { + if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, u4CmdLen)) { printk(KERN_INFO DRV_NAME"extra buffer is valid\n"); } else { @@ -4451,18 +4466,18 @@ mtk_p2p_wext_set_struct ( break; #if CFG_SUPPORT_ANTI_PIRACY case PRIV_SEC_CHECK_OID: - if (wrqu->data.length > 256) { + if (u4CmdLen > 256) { status = -EOPNOTSUPP; break; } if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), wrqu->data.pointer, - wrqu->data.length)) { + u4CmdLen)) { status = -EFAULT; break; } - if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), extra, wrqu->data.length)) { + if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), extra, u4CmdLen)) { printk(KERN_INFO DRV_NAME"extra buffer is valid\n"); } else { @@ -4480,14 +4495,20 @@ mtk_p2p_wext_set_struct ( break; #endif case PRIV_CMD_P2P_VERSION: + if (u4CmdLen > OID_SET_GET_STRUCT_LENGTH) { + printk(KERN_INFO DRV_NAME"input data length invalid %ld\n", u4CmdLen); + status = -EINVAL; + break; + } + if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, - wrqu->data.length)) { + u4CmdLen)) { status = -EFAULT; break; } - if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length)) { + if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, u4CmdLen)) { printk(KERN_INFO DRV_NAME"extra buffer is valid\n"); } else { @@ -4537,6 +4558,7 @@ mtk_p2p_wext_get_struct ( { int status = 0; UINT_32 u4SubCmd = 0; + UINT_32 u4CmdLen = 0; P_GLUE_INFO_T prGlueInfo = NULL; P_IW_P2P_TRANSPORT_STRUCT prP2PReq = NULL; @@ -4555,12 +4577,19 @@ mtk_p2p_wext_get_struct ( ASSERT(prGlueInfo); u4SubCmd = (UINT_32) wrqu->data.flags; + u4CmdLen = wrqu->data.length; kalMemZero(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), sizeof(prGlueInfo->prP2PInfo->aucOidBuf)); switch (u4SubCmd) { case PRIV_CMD_OID: + if (u4CmdLen > sizeof(IW_P2P_TRANSPORT_STRUCT)) { + printk(KERN_INFO DRV_NAME"input data length invalid %ld\n", u4CmdLen); + status = -EINVAL; + break; + } + if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { @@ -4582,10 +4611,10 @@ mtk_p2p_wext_get_struct ( case P2P_CMD_ID_INVITATION_INDICATE: { status = mtk_p2p_wext_invitation_indicate(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); - prP2PReq->outBufferLength = wrqu->data.length; + prP2PReq->outBufferLength = u4CmdLen; if (copy_to_user(wrqu->data.pointer, &(prGlueInfo->prP2PInfo->aucOidBuf[0]), - wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { + u4CmdLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { printk(KERN_NOTICE "%s() copy_to_user() fail\n", __func__); return -EIO; } @@ -4597,10 +4626,10 @@ mtk_p2p_wext_get_struct ( case P2P_CMD_ID_INVITATION_STATUS: { status = mtk_p2p_wext_invitation_status(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); - prP2PReq->outBufferLength = wrqu->data.length; + prP2PReq->outBufferLength = u4CmdLen; if (copy_to_user(wrqu->data.pointer, &(prGlueInfo->prP2PInfo->aucOidBuf[0]), - wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { + u4CmdLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { printk(KERN_NOTICE "%s() copy_to_user() fail\n", __func__); return -EIO; } @@ -4678,8 +4707,8 @@ mtk_p2p_wext_get_struct ( break; #if CFG_SUPPORT_ANTI_PIRACY case PRIV_SEC_CHECK_OID: - if (wrqu->data.length > 256) { - status = -EOPNOTSUPP; + if (u4CmdLen > sizeof(IW_P2P_TRANSPORT_STRUCT)) { + status = -EINVAL; break; } if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), @@ -4701,6 +4730,11 @@ mtk_p2p_wext_get_struct ( break; #endif case PRIV_CMD_P2P_VERSION: + if (u4CmdLen > sizeof(IW_P2P_TRANSPORT_STRUCT)) { + status = -EINVAL; + break; + } + if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { diff --git a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_wext.c b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_wext.c index 94c6ef3a1..99bf5c7bb 100644 --- a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_wext.c +++ b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_wext.c @@ -1792,7 +1792,7 @@ static int wext_set_scan ( IN struct net_device *prNetDev, IN struct iw_request_info *prIwrInfo, - IN union iwreq_data *prData, + IN struct iw_scan_req *prIwScanReq, IN char *pcExtra ) { @@ -1809,8 +1809,8 @@ wext_set_scan ( #if WIRELESS_EXT > 17 /* retrieve SSID */ - if(prData) { - essid_len = ((struct iw_scan_req *)(((struct iw_point*)prData)->pointer))->essid_len; + if(prIwScanReq) { + essid_len = prIwScanReq->essid_len; } #endif @@ -3975,6 +3975,7 @@ wext_support_ioctl ( int ret = 0; char *prExtraBuf = NULL; UINT_32 u4ExtraSize = 0; + struct iw_scan_req * prIwScanReq = NULL; /* prDev is verified in the caller function wlanDoIOCTL() */ @@ -4120,24 +4121,27 @@ wext_support_ioctl ( ret = wext_set_scan(prDev, NULL, NULL, NULL); } #if WIRELESS_EXT > 17 - else if (iwr->u.data.length == sizeof(struct iw_scan_req)) { - prExtraBuf = kalMemAlloc(MAX_SSID_LEN, VIR_MEM_TYPE); - if (!prExtraBuf) { - ret = -ENOMEM; - break; - } - if (copy_from_user(prExtraBuf, ((struct iw_scan_req *) (iwr->u.data.pointer))->essid, - ((struct iw_scan_req *) (iwr->u.data.pointer))->essid_len)) { - ret = -EFAULT; - } else { - ret = wext_set_scan(prDev, NULL, (union iwreq_data *) &(iwr->u.data), prExtraBuf); - } + else if (iwr->u.data.length == sizeof(struct iw_scan_req)) { + prIwScanReq = kalMemAlloc(sizeof(struct iw_scan_req), VIR_MEM_TYPE); + if (!prIwScanReq) { + ret = -ENOMEM; + break; + } - kalMemFree(prExtraBuf, VIR_MEM_TYPE, MAX_SSID_LEN); - prExtraBuf = NULL; + if (copy_from_user(prIwScanReq, iwr->u.data.pointer, sizeof(struct iw_scan_req))) { + ret = -EFAULT; + } else { + if (prIwScanReq->essid_len > IW_ESSID_MAX_SIZE) + prIwScanReq->essid_len = IW_ESSID_MAX_SIZE; + + ret = wext_set_scan(prDev, NULL, prIwScanReq, &(prIwScanReq->essid[0])); + } + + kalMemFree(prIwScanReq, VIR_MEM_TYPE, sizeof(struct iw_scan_req)); + prIwScanReq = NULL; } #endif - else { + else { ret = -EINVAL; } break; @@ -4188,7 +4192,8 @@ wext_support_ioctl ( #if 1 case SIOCSIWESSID: /* 0x8B1A, set SSID (network name) */ - if (iwr->u.essid.length > IW_ESSID_MAX_SIZE) { + u4ExtraSize = iwr->u.essid.length; + if (u4ExtraSize > IW_ESSID_MAX_SIZE) { ret = -E2BIG; break; } @@ -4205,7 +4210,7 @@ wext_support_ioctl ( if (copy_from_user(prExtraBuf, iwr->u.essid.pointer, - iwr->u.essid.length)) { + u4ExtraSize)) { ret = -EFAULT; } else { @@ -4223,14 +4228,14 @@ wext_support_ioctl ( #endif case SIOCGIWESSID: /* 0x8B1B, get SSID */ + u4ExtraSize = iwr->u.essid.length; if (!iwr->u.essid.pointer) { ret = -EINVAL; break; } - if (iwr->u.essid.length < IW_ESSID_MAX_SIZE) { - DBGLOG(INIT, INFO, ("[wifi] iwr->u.essid.length:%d too small\n", - iwr->u.essid.length)); + if (u4ExtraSize < IW_ESSID_MAX_SIZE) { + DBGLOG(INIT, INFO, ("[wifi] iwr->u.essid.length: %ld too small\n", u4ExtraSize)); ret = -E2BIG; /* let caller try larger buffer */ break; } @@ -4245,7 +4250,7 @@ wext_support_ioctl ( ret = wext_get_essid(prDev, NULL, &iwr->u.essid, prExtraBuf); if (ret == 0) { - if (copy_to_user(iwr->u.essid.pointer, prExtraBuf, iwr->u.essid.length)) { + if (copy_to_user(iwr->u.essid.pointer, prExtraBuf, u4ExtraSize)) { ret = -EFAULT; } } @@ -4294,25 +4299,26 @@ wext_support_ioctl ( case SIOCSIWENCODE: /* 0x8B2A, set encoding token & mode */ /* Only DISABLED case has NULL pointer and length == 0 */ if (iwr->u.encoding.pointer) { - if (iwr->u.encoding.length > 16) { + u4ExtraSize = iwr->u.encoding.length; + if (u4ExtraSize > 16) { ret = -E2BIG; break; } - u4ExtraSize = iwr->u.encoding.length; prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); - if (!prExtraBuf) { - ret = -ENOMEM; - break; - } - if (copy_from_user(prExtraBuf, + if (!prExtraBuf) { + ret = -ENOMEM; + break; + } + + if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, - iwr->u.encoding.length)) { + u4ExtraSize)) { ret = -EFAULT; } } - else if (iwr->u.encoding.length != 0) { + else { ret = -EINVAL; break; } @@ -4346,13 +4352,14 @@ wext_support_ioctl ( P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); if (1 /* wlanQueryWapiMode(prGlueInfo->prAdapter) */) { /* Fixed length structure */ + u4ExtraSize = iwr->u.data.length; + #if CFG_SUPPORT_WAPI - if (iwr->u.data.length > 42 /* The max wapi ie buffer */) { + if (u4ExtraSize > 42 /* The max wapi ie buffer */) { ret = -EINVAL; break; } #endif - u4ExtraSize = iwr->u.data.length; if (u4ExtraSize) { prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); if (!prExtraBuf) { @@ -4361,7 +4368,7 @@ wext_support_ioctl ( } if (copy_from_user(prExtraBuf, iwr->u.data.pointer, - iwr->u.data.length)) { + u4ExtraSize)) { ret = -EFAULT; } else { @@ -4425,6 +4432,11 @@ wext_support_ioctl ( case SIOCSIWENCODEEXT: /* 0x8B34, set extended encoding token & mode */ if (iwr->u.encoding.pointer) { u4ExtraSize = iwr->u.encoding.length; + if (u4ExtraSize > sizeof(struct iw_encode_ext)) { + ret = -EINVAL; + break; + } + prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); if (!prExtraBuf) { ret = -ENOMEM; @@ -4433,11 +4445,11 @@ wext_support_ioctl ( if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, - iwr->u.encoding.length)) { + u4ExtraSize)) { ret = -EFAULT; } } - else if (iwr->u.encoding.length != 0) { + else { ret = -EINVAL; break; } @@ -4575,7 +4587,7 @@ wext_support_ioctl ( prExtraBuf = NULL; } } - else if (iwr->u.data.length != 0) { + else { ret = -EINVAL; break; } diff --git a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_wext_priv.c b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_wext_priv.c index 7b290b931..32420ed8d 100644 --- a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_wext_priv.c +++ b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_wext_priv.c @@ -293,6 +293,7 @@ #define CMD_SET_CFG "SET_CFG" #define CMD_GET_CFG "GET_CFG" #define CMD_SET_CHIP "SET_CHIP" +#define CMD_OID_BUF_LENGTH 4096 #define CMD_GET_CHIP "GET_CHIP" #define CMD_SET_DBG_LEVEL "SET_DBG_LEVEL" #define CMD_GET_DBG_LEVEL "GET_DBG_LEVEL" @@ -392,7 +393,7 @@ reqExtSetAcpiDevicePowerState ( * P R I V A T E D A T A ******************************************************************************** */ -static UINT_8 aucOidBuf[4096] = {0}; +static UINT_8 aucOidBuf[CMD_OID_BUF_LENGTH] = {0}; /* OID processing table */ /* Order is important here because the OIDs should be in order of @@ -1939,30 +1940,39 @@ priv_set_struct ( #if CFG_SUPPORT_WPS2 case PRIV_CMD_WSC_PROBE_REQ: - { - /* retrieve IE for Probe Request */ - if (prIwReqData->data.length > 0) { - if (copy_from_user(prGlueInfo->aucWSCIE, prIwReqData->data.pointer, - prIwReqData->data.length)) { + { + /* retrieve IE for Probe Request */ + u4CmdLen = prIwReqData->data.length; + if (u4CmdLen > GLUE_INFO_WSCIE_LENGTH) { + DBGLOG(REQ, ERROR, ("Input data length is invalid %ld\n", u4CmdLen)); + return -EINVAL; + } + + if (u4CmdLen > 0) { + if (copy_from_user(prGlueInfo->aucWSCIE, prIwReqData->data.pointer,u4CmdLen)) { status = -EFAULT; - break; + break; } - prGlueInfo->u2WSCIELen = prIwReqData->data.length; + prGlueInfo->u2WSCIELen = u4CmdLen; } - else { - prGlueInfo->u2WSCIELen = 0; - } - } - break; + else { + prGlueInfo->u2WSCIELen = 0; + } + } + break; #endif case PRIV_CMD_OID: - if (copy_from_user(&aucOidBuf[0], - prIwReqData->data.pointer, - prIwReqData->data.length)) { + u4CmdLen = prIwReqData->data.length; + if (u4CmdLen > CMD_OID_BUF_LENGTH) { + DBGLOG(REQ, ERROR, ("Input data length is invalid %ld\n", u4CmdLen)); + return -EINVAL; + } + + if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) { status = -EFAULT; break; } - if (!kalMemCmp(&aucOidBuf[0], pcExtra, prIwReqData->data.length)) { + if (!kalMemCmp(&aucOidBuf[0], pcExtra, u4CmdLen)) { DBGLOG(REQ, INFO, ("pcExtra buffer is valid\n")); } else @@ -1984,12 +1994,18 @@ priv_set_struct ( case PRIV_CMD_SW_CTRL: pu4IntBuf = (PUINT_32)prIwReqData->data.pointer; + u4CmdLen = prIwReqData->data.length; prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; + if(u4CmdLen > sizeof(prNdisReq->ndisOidContent)) { + DBGLOG(REQ, ERROR, ("Input data length is invalid %ld\n", u4CmdLen)); + return -EINVAL; + } + //kalMemCopy(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, 8); if (copy_from_user(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, - prIwReqData->data.length)) { + u4CmdLen)) { status = -EFAULT; break; } @@ -2636,9 +2652,12 @@ priv_set_string( InBufLen = prIwReqData->data.length; Status = 0; - if (copy_from_user(InBuf, - prIwReqData->data.pointer, - prIwReqData->data.length)) { + if (InBufLen > CMD_OID_BUF_LENGTH) { + DBGLOG(REQ, ERROR, ("Input data length is invalid %ld\n", InBufLen)); + return -EINVAL; + } + + if (copy_from_user(InBuf, prIwReqData->data.pointer, InBufLen)) { return -EFAULT; } diff --git a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/include/gl_os.h b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/include/gl_os.h index 3ef9f4815..cfd5442c2 100644 --- a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/include/gl_os.h +++ b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/include/gl_os.h @@ -651,6 +651,7 @@ extern BOOLEAN fgIsBusAccessFailed; //#define GLUE_BOW_DEVICE_NAME "MT6620 802.11 AMP" #define GLUE_BOW_DEVICE_NAME "ampc0" +#define GLUE_INFO_WSCIE_LENGTH 500 /******************************************************************************* * D A T A T Y P E S @@ -900,9 +901,9 @@ struct _GLUE_INFO_T { #endif #endif BOOLEAN fgWpsActive; - UINT_8 aucWSCIE[500]; /*for probe req*/ + UINT_8 aucWSCIE[GLUE_INFO_WSCIE_LENGTH]; /*for probe req*/ UINT_16 u2WSCIELen; - UINT_8 aucWSCAssocInfoIE[200]; /*for Assoc req*/ + UINT_8 aucWSCAssocInfoIE[200]; /*for Assoc req*/ UINT_16 u2WSCAssocInfoIELen; #ifdef CONFIG_NL80211_FASTSCAN char prio_ssid[10][32]; @@ -910,10 +911,10 @@ struct _GLUE_INFO_T { #endif #if CFG_SUPPORT_HOTSPOT_2_0 - UINT_8 aucHS20AssocInfoIE[200]; /*for Assoc req*/ - UINT_16 u2HS20AssocInfoIELen; - UINT_8 ucHotspotConfig; - BOOLEAN fgConnectHS20AP; + UINT_8 aucHS20AssocInfoIE[200]; /*for Assoc req*/ + UINT_16 u2HS20AssocInfoIELen; + UINT_8 ucHotspotConfig; + BOOLEAN fgConnectHS20AP; #endif /* NVRAM availability */ diff --git a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/include/gl_p2p_os.h b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/include/gl_p2p_os.h index 06782d9ca..0ad2474c0 100644 --- a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/include/gl_p2p_os.h +++ b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/include/gl_p2p_os.h @@ -119,7 +119,7 @@ struct _GL_P2P_INFO_T { UINT_32 u4InvStatus; /* For SET_STRUCT/GET_STRUCT */ - UINT_8 aucOidBuf[4096]; + UINT_8 aucOidBuf[OID_SET_GET_STRUCT_LENGTH]; #if 1 /* CFG_SUPPORT_ANTI_PIRACY */ UINT_8 aucSecCheck[256]; |
