wcnss: fix the race condition issue during cal data extraction
The wcnss platform driver update the wlan calibration data by the user space wlan daemon. The wlan user space daemon store the updated wlan calibration data reported by wlan firmware in user space and write it back to the wcnss platform calibration data buffer for the calibration data download and update. During the wlan calibration data extraction there are some potential race condition which leads to memory leak and buffer overflow during the context switch. Fix the above issue by adding protection code. CRs-Fixed: 2015791 Change-Id: I231807f6b2d8094d7138b95c659ed6272897ba2d Signed-off-by: Sarada Prasanna Garnayak <sgarna@codeaurora.org>
This commit is contained in:
parent
6cf6835d96
commit
bf00f32974
1 changed files with 8 additions and 9 deletions
|
@ -2045,21 +2045,23 @@ void extract_cal_data(int len)
|
|||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&penv->dev_lock);
|
||||
rc = smd_read(penv->smd_ch, (unsigned char *)&calhdr,
|
||||
sizeof(struct cal_data_params));
|
||||
if (rc < sizeof(struct cal_data_params)) {
|
||||
pr_err("wcnss: incomplete cal header read from smd\n");
|
||||
mutex_unlock(&penv->dev_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (penv->fw_cal_exp_frag != calhdr.frag_number) {
|
||||
pr_err("wcnss: Invalid frgament");
|
||||
goto exit;
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
if (calhdr.frag_size > WCNSS_MAX_FRAME_SIZE) {
|
||||
pr_err("wcnss: Invalid fragment size");
|
||||
goto exit;
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
if (penv->fw_cal_available) {
|
||||
|
@ -2068,8 +2070,9 @@ void extract_cal_data(int len)
|
|||
penv->fw_cal_exp_frag++;
|
||||
if (calhdr.msg_flags & LAST_FRAGMENT) {
|
||||
penv->fw_cal_exp_frag = 0;
|
||||
goto exit;
|
||||
goto unlock_exit;
|
||||
}
|
||||
mutex_unlock(&penv->dev_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2077,7 +2080,7 @@ void extract_cal_data(int len)
|
|||
if (calhdr.total_size > MAX_CALIBRATED_DATA_SIZE) {
|
||||
pr_err("wcnss: Invalid cal data size %d",
|
||||
calhdr.total_size);
|
||||
goto exit;
|
||||
goto unlock_exit;
|
||||
}
|
||||
kfree(penv->fw_cal_data);
|
||||
penv->fw_cal_rcvd = 0;
|
||||
|
@ -2085,11 +2088,10 @@ void extract_cal_data(int len)
|
|||
GFP_KERNEL);
|
||||
if (penv->fw_cal_data == NULL) {
|
||||
smd_read(penv->smd_ch, NULL, calhdr.frag_size);
|
||||
goto exit;
|
||||
goto unlock_exit;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&penv->dev_lock);
|
||||
if (penv->fw_cal_rcvd + calhdr.frag_size >
|
||||
MAX_CALIBRATED_DATA_SIZE) {
|
||||
pr_err("calibrated data size is more than expected %d",
|
||||
|
@ -2124,13 +2126,10 @@ void extract_cal_data(int len)
|
|||
|
||||
unlock_exit:
|
||||
mutex_unlock(&penv->dev_lock);
|
||||
|
||||
exit:
|
||||
wcnss_send_cal_rsp(fw_status);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void wcnssctrl_rx_handler(struct work_struct *worker)
|
||||
{
|
||||
int len = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue