aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authoryang-cy.chen <yang-cy.chen@mediatek.com>2016-03-16 03:03:06 +0800
committerMoyster <oysterized@gmail.com>2016-08-26 16:02:17 +0200
commitf5bb9a717fb164d134064c24a88038e126e36ea2 (patch)
tree9f871e1bdd4398cf26b1d0a6a282603e20cc3673 /drivers
parented4fff76be6333a98a6736bc2550fffb7d5e8053 (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')
-rw-r--r--drivers/misc/mediatek/connectivity/conn_soc/common/linux/pub/wmt_chrdev_wifi.c6
-rw-r--r--drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/include/wlan_lib.h2
-rw-r--r--drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_p2p.c92
-rw-r--r--drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_wext.c90
-rw-r--r--drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_wext_priv.c61
-rw-r--r--drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/include/gl_os.h13
-rw-r--r--drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/include/gl_p2p_os.h2
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];