qcacmn: Fix use-after-freed when sending WMI command to FW
Using a buffer after passing it to wmi_unified_cmd_send() induces a race condition that may result in a use-after-freed situation. Fix several potential use-after-freed situations when calling wmi_unified_cmd_send() by ensuring all access to a buffer is done before the call to wmi_unified_cmd_send(). Change-Id: I985aad6e49daf1d823e3751a9cb0a293a298323c CRs-Fixed: 1089713
This commit is contained in:
@@ -1738,6 +1738,8 @@ static bool wmi_is_pm_resume_cmd(uint32_t cmd_id)
|
||||
* @len: wmi buffer length
|
||||
* @cmd_id: wmi command id
|
||||
*
|
||||
* Note, it is NOT safe to access buf after calling this function!
|
||||
*
|
||||
* Return: 0 on success
|
||||
*/
|
||||
QDF_STATUS wmi_unified_cmd_send(wmi_unified_t wmi_handle, wmi_buf_t buf,
|
||||
|
@@ -777,7 +777,7 @@ QDF_STATUS send_green_ap_ps_cmd_non_tlv(wmi_unified_t wmi_handle,
|
||||
qdf_print("%s: Sent WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID.\n"
|
||||
"enable=%u status=%d\n",
|
||||
__func__,
|
||||
cmd->enable,
|
||||
value,
|
||||
ret);
|
||||
#endif /* OL_GREEN_AP_DEBUG_CONFIG_INTERACTIONS */
|
||||
return ret;
|
||||
@@ -2324,19 +2324,23 @@ QDF_STATUS send_smart_ant_enable_cmd_non_tlv(wmi_unified_t wmi_handle,
|
||||
|
||||
if (ret != 0) {
|
||||
qdf_print(" %s :WMI Failed\n", __func__);
|
||||
qdf_print("%s: Sent WMI_PDEV_SMART_ANT_ENABLE_CMDID.\n"
|
||||
qdf_print("%s: Failed to send WMI_PDEV_SMART_ANT_ENABLE_CMDID.\n"
|
||||
"enable:%d mode:%d rx_antenna: 0x%08x PINS: "
|
||||
"[%d %d %d %d] Func[%d %d %d %d] cmdstatus=%d\n",
|
||||
__func__,
|
||||
cmd->enable,
|
||||
cmd->mode,
|
||||
cmd->rx_antenna,
|
||||
cmd->gpio_pin[0], cmd->gpio_pin[1],
|
||||
cmd->gpio_pin[2], cmd->gpio_pin[3],
|
||||
cmd->gpio_func[0], cmd->gpio_func[1],
|
||||
cmd->gpio_func[2], cmd->gpio_func[3],
|
||||
cmd->gpio_pin[0],
|
||||
cmd->gpio_pin[1],
|
||||
cmd->gpio_pin[2],
|
||||
cmd->gpio_pin[3],
|
||||
cmd->gpio_func[0],
|
||||
cmd->gpio_func[1],
|
||||
cmd->gpio_func[2],
|
||||
cmd->gpio_func[3],
|
||||
ret);
|
||||
|
||||
wmi_buf_free(buf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -2371,11 +2375,12 @@ QDF_STATUS send_smart_ant_set_rx_ant_cmd_non_tlv(wmi_unified_t wmi_handle,
|
||||
|
||||
if (ret != 0) {
|
||||
qdf_print(" %s :WMI Failed\n", __func__);
|
||||
qdf_print("%s: Sent WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID.\n"
|
||||
qdf_print("%s: Failed to send WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID.\n"
|
||||
" rx_antenna: 0x%08x cmdstatus=%d\n",
|
||||
__func__,
|
||||
cmd->rx_antenna,
|
||||
ret);
|
||||
wmi_buf_free(buf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -2416,13 +2421,14 @@ QDF_STATUS send_smart_ant_set_tx_ant_cmd_non_tlv(wmi_unified_t wmi_handle,
|
||||
|
||||
if (ret != 0) {
|
||||
qdf_print(" %s :WMI Failed\n", __func__);
|
||||
qdf_print("%s: Sent WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID.\n"
|
||||
qdf_print("%s: Failed to send WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID.\n"
|
||||
" Node: %s tx_antennas: [0x%08x 0x%08x] cmdstatus=%d\n",
|
||||
__func__,
|
||||
ether_sprintf(macaddr),
|
||||
cmd->antenna_series[0],
|
||||
cmd->antenna_series[1],
|
||||
ret);
|
||||
wmi_buf_free(buf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -2467,15 +2473,17 @@ QDF_STATUS send_smart_ant_set_training_info_cmd_non_tlv(
|
||||
|
||||
if (ret != 0) {
|
||||
qdf_print(" %s :WMI Failed\n", __func__);
|
||||
qdf_print("%s: Sent WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID.\n"
|
||||
qdf_print("%s: Failed to Send WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID.\n"
|
||||
" Train Node: %s rate_array[0x%02x 0x%02x] "
|
||||
"tx_antennas: [0x%08x 0x%08x] cmdstatus=%d\n",
|
||||
__func__,
|
||||
ether_sprintf(macaddr),
|
||||
cmd->train_rate_series[0], cmd->train_rate_series[1],
|
||||
cmd->train_rate_series[0],
|
||||
cmd->train_rate_series[1],
|
||||
cmd->train_antenna_series[0],
|
||||
cmd->train_antenna_series[1],
|
||||
ret);
|
||||
wmi_buf_free(buf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -2656,25 +2664,25 @@ QDF_STATUS send_vdev_spectral_configure_cmd_non_tlv(wmi_unified_t wmi_handle,
|
||||
"spectral_scan_bin_scale = %u\n"
|
||||
"spectral_scan_dBm_adj = %u\n"
|
||||
"spectral_scan_chn_mask = %u\n",
|
||||
cmd->vdev_id,
|
||||
cmd->spectral_scan_count,
|
||||
cmd->spectral_scan_period,
|
||||
cmd->spectral_scan_priority,
|
||||
cmd->spectral_scan_fft_size,
|
||||
cmd->spectral_scan_gc_ena,
|
||||
cmd->spectral_scan_restart_ena,
|
||||
cmd->spectral_scan_noise_floor_ref,
|
||||
cmd->spectral_scan_init_delay,
|
||||
cmd->spectral_scan_nb_tone_thr,
|
||||
cmd->spectral_scan_str_bin_thr,
|
||||
cmd->spectral_scan_wb_rpt_mode,
|
||||
cmd->spectral_scan_rssi_rpt_mode,
|
||||
cmd->spectral_scan_rssi_thr,
|
||||
cmd->spectral_scan_pwr_format,
|
||||
cmd->spectral_scan_rpt_mode,
|
||||
cmd->spectral_scan_bin_scale,
|
||||
cmd->spectral_scan_dBm_adj,
|
||||
cmd->spectral_scan_chn_mask);
|
||||
param->vdev_id,
|
||||
param->count,
|
||||
param->period,
|
||||
param->spectral_pri,
|
||||
param->fft_size,
|
||||
param->gc_enable,
|
||||
param->restart_enable,
|
||||
param->noise_floor_ref,
|
||||
param->init_delay,
|
||||
param->nb_tone_thr,
|
||||
param->str_bin_thr,
|
||||
param->wb_rpt_mode,
|
||||
param->rssi_rpt_mode,
|
||||
param->rssi_thr,
|
||||
param->pwr_format,
|
||||
param->rpt_mode,
|
||||
param->bin_scale,
|
||||
param->dBm_adj,
|
||||
param->chn_mask);
|
||||
qdf_print("%s: Status: %d\n\n", __func__, ret);
|
||||
#endif /* OL_SPECTRAL_DEBUG_CONFIG_INTERACTIONS */
|
||||
|
||||
|
@@ -8319,6 +8319,10 @@ QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle,
|
||||
(clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET);
|
||||
cmd->vdev_id = vdev_id;
|
||||
WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr);
|
||||
|
||||
WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: %pM",
|
||||
cmd->action, vdev_id, clearList, multicast_addr.bytes);
|
||||
|
||||
err = wmi_unified_cmd_send(wmi_handle, buf,
|
||||
sizeof(*cmd),
|
||||
WMI_SET_MCASTBCAST_FILTER_CMDID);
|
||||
@@ -8327,11 +8331,8 @@ QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle,
|
||||
wmi_buf_free(buf);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d",
|
||||
cmd->action, vdev_id, clearList);
|
||||
WMI_LOGD("MCBC MAC Addr: %pM", multicast_addr.bytes);
|
||||
|
||||
return 0;
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8385,6 +8386,8 @@ QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
|
||||
cmd->flags = gtk_offload_opcode;
|
||||
}
|
||||
|
||||
WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x", vdev_id, cmd->flags);
|
||||
|
||||
/* send the wmi command */
|
||||
if (wmi_unified_cmd_send(wmi_handle, buf, len,
|
||||
WMI_GTK_OFFLOAD_CMDID)) {
|
||||
@@ -8393,7 +8396,6 @@ QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x", vdev_id, cmd->flags);
|
||||
out:
|
||||
WMI_LOGD("%s Exit", __func__);
|
||||
return status;
|
||||
|
Reference in New Issue
Block a user