net: wireless: bcmdhd: fix for IOVAR GET failed

found some case that IOVAR callers set response buffer not enough to
contain input command string + argument. so it finally fail in IOVAR
transaction by its shorter buffer length.

proposed fix is taking care this case by providing enough local
buffer inside dhd_iovar, which enough to input/output.

[backported to manta: Corinna Vinschen <xda@vinschen.de>]

Signed-off-by: Insun Song <insun.song@broadcom.com>
Signed-off-by: Corinna Vinschen <xda@vinschen.de>
Bug: 36000515
Change-Id: I0afedcc29b05b12f42ebc619e6feeaa868fc00de
This commit is contained in:
Insun Song 2017-03-24 14:04:03 -07:00 committed by ShevT
parent 8ef49fa7c5
commit 90282f08c4
1 changed files with 24 additions and 7 deletions

View File

@ -5440,26 +5440,43 @@ done:
int
dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len, int set)
dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *param_buf,
uint param_len, int set)
{
char buf[strlen(name) + 1 + cmd_len];
int len = sizeof(buf);
char *buf;
int input_len;
wl_ioctl_t ioc;
int ret;
len = bcm_mkiovar(name, cmd_buf, cmd_len, buf, len);
if (param_len > WLC_IOCTL_MAXLEN)
return BCME_BADARG;
input_len = strlen(name) + 1 + param_len;
if (input_len > WLC_IOCTL_MAXLEN)
return BCME_BADARG;
buf = kzalloc(input_len, GFP_KERNEL);
if (!buf) {
DHD_ERROR(("%s: mem alloc failed\n", __FUNCTION__));
return BCME_NOMEM;
}
ret = bcm_mkiovar(name, param_buf, param_len, buf, input_len);
if (!ret) {
ret = BCME_NOMEM;
goto exit;
}
memset(&ioc, 0, sizeof(ioc));
ioc.cmd = set? WLC_SET_VAR : WLC_GET_VAR;
ioc.buf = buf;
ioc.len = len;
ioc.len = input_len;
ioc.set = set;
ret = dhd_wl_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len);
if (!set && ret >= 0)
memcpy(cmd_buf, buf, cmd_len);
memcpy(param_buf, buf, param_len);
exit:
kfree(buf);
return ret;
}