summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDustin Brown <dustinb@codeaurora.org>2016-11-14 16:11:26 -0800
committerqcabuildsw <qcabuildsw@localhost>2016-11-16 01:59:26 -0800
commitf28d76bb3c7ec156c6944009f04aca05c437405c (patch)
tree0f64136e13bc6a3866528a16078ba30922a6c682
parentf35a83e74c2876b0ba82e912a8fdd05821b901d6 (diff)
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
-rw-r--r--wmi/src/wmi_unified.c2
-rw-r--r--wmi/src/wmi_unified_non_tlv.c94
-rw-r--r--wmi/src/wmi_unified_tlv.c12
3 files changed, 60 insertions, 48 deletions
diff --git a/wmi/src/wmi_unified.c b/wmi/src/wmi_unified.c
index 6f2960286e22..9746fe3d539a 100644
--- a/wmi/src/wmi_unified.c
+++ b/wmi/src/wmi_unified.c
@@ -1721,6 +1721,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,
diff --git a/wmi/src/wmi_unified_non_tlv.c b/wmi/src/wmi_unified_non_tlv.c
index ecfb6be805a1..85c799b91a0b 100644
--- a/wmi/src/wmi_unified_non_tlv.c
+++ b/wmi/src/wmi_unified_non_tlv.c
@@ -714,7 +714,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;
@@ -2255,19 +2255,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"
- "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],
- ret);
-
+ 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],
+ ret);
+ wmi_buf_free(buf);
}
return ret;
}
@@ -2302,11 +2306,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"
- " rx_antenna: 0x%08x cmdstatus=%d\n",
- __func__,
- cmd->rx_antenna,
- ret);
+ 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;
}
@@ -2347,13 +2352,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;
}
@@ -2398,15 +2404,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);
+ cmd->train_antenna_series[1],
+ ret);
+ wmi_buf_free(buf);
}
return ret;
}
@@ -2587,25 +2595,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 */
diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c
index 83b4a8be28f4..7d598eab6297 100644
--- a/wmi/src/wmi_unified_tlv.c
+++ b/wmi/src/wmi_unified_tlv.c
@@ -7915,6 +7915,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);
@@ -7923,11 +7927,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;
}
/**
@@ -7981,6 +7982,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)) {
@@ -7989,7 +7992,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;