diff options
| author | Dustin Brown <dustinb@codeaurora.org> | 2016-11-14 16:11:26 -0800 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2016-11-16 01:59:26 -0800 |
| commit | f28d76bb3c7ec156c6944009f04aca05c437405c (patch) | |
| tree | 0f64136e13bc6a3866528a16078ba30922a6c682 | |
| parent | f35a83e74c2876b0ba82e912a8fdd05821b901d6 (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.c | 2 | ||||
| -rw-r--r-- | wmi/src/wmi_unified_non_tlv.c | 94 | ||||
| -rw-r--r-- | wmi/src/wmi_unified_tlv.c | 12 |
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; |
