net: wireless: bcmdhd: remove SDIO debug IOVARs causing out of bounds

"sd_devreg" IOVAR can cause out of bounds access when user input
manipulated. Proposed fix is removing debug oriented IOVARs completely.

Signed-off-by: Insun Song <insun.song@broadcom.com>
Bug: 37622847
Change-Id: I8fc5111fe9d8d2c5d7ae5b1c24ae8e531113beae
CVE-2017-0824
Signed-off-by: Kevin F. Haggerty <haggertk@lineageos.org>
This commit is contained in:
Insun Song 2017-07-07 14:53:03 -07:00 committed by Francescodario Cuzzocrea
parent e51b81941a
commit 6ad830b67f

View file

@ -406,8 +406,6 @@ const bcm_iovar_t sdioh_iovars[] = {
{"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0 },
{"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0 },
{"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0 },
{"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t) },
{"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t) },
{"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0 },
{"sd_power", IOV_POWER, 0, IOVT_UINT32, 0 },
{"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0 },
@ -621,73 +619,6 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name,
bcopy(&int_val, arg, val_size);
break;
case IOV_GVAL(IOV_HOSTREG):
{
sdreg_t *sd_ptr = (sdreg_t *)params;
if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) {
sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset));
bcmerror = BCME_BADARG;
break;
}
sd_trace(("%s: rreg%d at offset %d\n", __FUNCTION__,
(sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32),
sd_ptr->offset));
if (sd_ptr->offset & 1)
int_val = 8; /* sdioh_sdmmc_rreg8(si, sd_ptr->offset); */
else if (sd_ptr->offset & 2)
int_val = 16; /* sdioh_sdmmc_rreg16(si, sd_ptr->offset); */
else
int_val = 32; /* sdioh_sdmmc_rreg(si, sd_ptr->offset); */
bcopy(&int_val, arg, sizeof(int_val));
break;
}
case IOV_SVAL(IOV_HOSTREG):
{
sdreg_t *sd_ptr = (sdreg_t *)params;
if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) {
sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset));
bcmerror = BCME_BADARG;
break;
}
sd_trace(("%s: wreg%d value 0x%08x at offset %d\n", __FUNCTION__, sd_ptr->value,
(sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32),
sd_ptr->offset));
break;
}
case IOV_GVAL(IOV_DEVREG):
{
sdreg_t *sd_ptr = (sdreg_t *)params;
uint8 data = 0;
if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) {
bcmerror = BCME_SDIO_ERROR;
break;
}
int_val = (int)data;
bcopy(&int_val, arg, sizeof(int_val));
break;
}
case IOV_SVAL(IOV_DEVREG):
{
sdreg_t *sd_ptr = (sdreg_t *)params;
uint8 data = (uint8)sd_ptr->value;
if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) {
bcmerror = BCME_SDIO_ERROR;
break;
}
break;
}
default:
bcmerror = BCME_UNSUPPORTED;
break;