2012-11-13 21:04:44

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH] staging: vt6656: iwctl_giwaplist/device_ioctl : use off stack buffers.

Calls ioctl SIOCGIWAPLIST use off stack buffers.

clears up warning messages.
main_usb.c:2015:1: warning: the frame size of 1888 bytes is larger than 1024 bytes [-Wframe-larger-than=]
iwctl.c:683:1: warning: the frame size of 1280 bytes is larger than 1024 bytes [-Wframe-larger-than=]

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/iwctl.c | 73 +++++++++++++++++++++----------------
drivers/staging/vt6656/main_usb.c | 46 +++++++++++++----------
2 files changed, 68 insertions(+), 51 deletions(-)

diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c
index 706e2a6..a914d20 100644
--- a/drivers/staging/vt6656/iwctl.c
+++ b/drivers/staging/vt6656/iwctl.c
@@ -632,47 +632,56 @@ int iwctl_giwap(struct net_device *dev, struct iw_request_info *info,
* Wireless Handler: get ap list
*/
int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *wrq, char *extra)
+ struct iw_point *wrq, u8 *extra)
{
+ struct sockaddr *sock;
+ struct iw_quality *qual;
+ PSDevice pDevice = netdev_priv(dev);
+ PSMgmtObject pMgmt = &pDevice->sMgmtObj;
+ PKnownBSS pBSS = &pMgmt->sBSSList[0];
int ii;
int jj;
- int rc = 0;
- struct sockaddr sock[IW_MAX_AP];
- struct iw_quality qual[IW_MAX_AP];
- PSDevice pDevice = netdev_priv(dev);
- PSMgmtObject pMgmt = &(pDevice->sMgmtObj);

- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n");
- // Only super-user can see AP list
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST\n");
+ /* Only super-user can see AP list */

- if (!capable(CAP_NET_ADMIN)) {
- rc = -EPERM;
- return rc;
- }
+ if (pBSS == NULL)
+ return -ENODEV;

- if (wrq->pointer) {
- PKnownBSS pBSS = &(pMgmt->sBSSList[0]);
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;

- for (ii = 0, jj= 0; ii < MAX_BSS_NUM; ii++) {
- pBSS = &(pMgmt->sBSSList[ii]);
- if (!pBSS->bActive)
- continue;
- if (jj >= IW_MAX_AP)
- break;
- memcpy(sock[jj].sa_data, pBSS->abyBSSID, 6);
- sock[jj].sa_family = ARPHRD_ETHER;
- qual[jj].level = pBSS->uRSSI;
- qual[jj].qual = qual[jj].noise = 0;
- qual[jj].updated = 2;
- jj++;
- }
+ if (!wrq->pointer)
+ return -EINVAL;
+
+ sock = kzalloc(sizeof(struct sockaddr) * IW_MAX_AP, GFP_KERNEL);
+ qual = kzalloc(sizeof(struct iw_quality) * IW_MAX_AP, GFP_KERNEL);
+ if (sock == NULL || qual == NULL)
+ return -ENOMEM;

- wrq->flags = 1; // Should be defined
- wrq->length = jj;
- memcpy(extra, sock, sizeof(struct sockaddr) * jj);
- memcpy(extra + sizeof(struct sockaddr) * jj, qual, sizeof(struct iw_quality) * jj);
+ for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) {
+ if (!pBSS[ii].bActive)
+ continue;
+ if (jj >= IW_MAX_AP)
+ break;
+ memcpy(sock[jj].sa_data, pBSS[ii].abyBSSID, 6);
+ sock[jj].sa_family = ARPHRD_ETHER;
+ qual[jj].level = pBSS[ii].uRSSI;
+ qual[jj].qual = qual[jj].noise = 0;
+ qual[jj].updated = 2;
+ jj++;
}
- return rc;
+
+ wrq->flags = 1; /* Should be defined */
+ wrq->length = jj;
+ memcpy(extra, sock, sizeof(struct sockaddr) * jj);
+ memcpy(extra + sizeof(struct sockaddr) * jj, qual,
+ sizeof(struct iw_quality) * jj);
+
+ kfree(sock);
+ kfree(qual);
+
+ return 0;
}

/*
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index d8cb093..f3c44ae 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -1555,12 +1555,12 @@ static struct net_device_stats *device_get_stats(struct net_device *dev) {


static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
- PSDevice pDevice = (PSDevice)netdev_priv(dev);
- PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
- PSCmdRequest pReq;
- //BOOL bCommit = FALSE;
+ PSDevice pDevice = (PSDevice)netdev_priv(dev);
+ PSMgmtObject pMgmt = &pDevice->sMgmtObj;
+ PSCmdRequest pReq;
+ u8 *buffer;
struct iwreq *wrq = (struct iwreq *) rq;
- int rc =0;
+ int rc = 0;

if (pMgmt == NULL) {
rc = -EFAULT;
@@ -1797,20 +1797,28 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
break;

case SIOCGIWAPLIST:
- {
- char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
-
- if (wrq->u.data.pointer) {
- rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
- if (rc == 0) {
- if (copy_to_user(wrq->u.data.pointer,
- buffer,
- (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality)))
- ))
- rc = -EFAULT;
- }
- }
- }
+ if (wrq->u.data.pointer) {
+ buffer = kzalloc((sizeof(struct sockaddr) +
+ sizeof(struct iw_quality)) * IW_MAX_AP,
+ GFP_KERNEL);
+ if (buffer == NULL) {
+ rc = -ENOMEM;
+ break;
+ }
+
+ rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
+ if (rc < 0) {
+ kfree(buffer);
+ break;
+ }
+
+ if (copy_to_user(wrq->u.data.pointer, buffer,
+ wrq->u.data.length * (sizeof(struct sockaddr)
+ + sizeof(struct iw_quality))))
+ rc = -EFAULT;
+
+ kfree(buffer);
+ }
break;


--
1.7.10.4